El objetivo de este trabajo es analizar a través de tablas y gráficos los perfiles (edad y sexo) de las personas que más están involucradas en accidentes de tráfico y visualizar a través de un mapa la localización de los accidentes que han causado la muerte de las víctimas. Los datos los descargamos de la págína del ayuntamiento de Barcelona de los años 2016 y 2017 e involucran dos archivos CSV: Personas involucradas y Vehículos.

Importación y limpieza de datos

Importamos los archivos ccvs de personas involucradas y vemos las primeras 5 líneas. En el caso de las coordenadas, al importarlas de forma standard se eliminaban los decimales, es por esto que tuvimos que cambiar la , por . y luego convertir el campo en numerico.

install.packages("readr")
Error in install.packages : Updating loaded packages
library(readr)
delim = ","
dec = ","
personas2016 <- read.csv("2016_accidents_persones_gu_bcn.csv", header=TRUE, sep=delim, dec=dec, stringsAsFactors=FALSE)
class(personas2016$Coordenada_UTM_.X.)
[1] "character"
options(digits=10)
personas2016$Coordenada_UTM_.X. <- (gsub(",", ".", as.character(personas2016$Coordenada_UTM_.X.)))
personas2016$Coordenada_UTM_.X. <- as.numeric(personas2016$Coordenada_UTM_.X.)
personas2016$Coordenada_UTM_.Y. <- (gsub(",", ".", as.character(personas2016$Coordenada_UTM_.Y.)))
personas2016$Coordenada_UTM_.Y. <- as.numeric(personas2016$Coordenada_UTM_.Y.)
head(personas2016)
personas2017<- read.csv("2017_accidents_persones_gu_bcn_.csv", header= TRUE, sep=",")
head(personas2017)
class(personas2017$Coordenada_UTM_.X.)
[1] "factor"
options(digits=10)
personas2017$Coordenada_UTM_.X.<- (gsub(",", ".", as.character(personas2017$Coordenada_UTM_.X.)))
personas2017$Coordenada_UTM_.X. <- as.numeric(personas2017$Coordenada_UTM_.X.)
personas2017$Coordenada_UTM_.Y. <- (gsub(",", ".", as.character(personas2017$Coordenada_UTM_.Y.)))
personas2017$Coordenada_UTM_.Y. <- as.numeric(personas2017$Coordenada_UTM_.Y.)
head(personas2017)

Estudiamos la estructura y dimensión de los dos DataFrames.

dim(personas2016)
[1] 12072    28
dim(personas2017)
[1] 12148    28
str(personas2016)
'data.frame':   12072 obs. of  28 variables:
 $ Número_d.expedient          : chr  "2016S000001    " "2016S000002    " "2016S000003    " "2016S000004    " ...
 $ Codi_districte              : int  2 1 8 2 2 2 8 7 5 8 ...
 $ Nom.districte               : chr  "Eixample" "Ciutat Vella" "Nou Barris" "Eixample" ...
 $ Codi_barri                  : int  7 3 53 8 8 8 56 35 27 48 ...
 $ Nom_barri                   : chr  "la Dreta de l'Eixample" "la Barceloneta" "la Trinitat Nova" "l'Antiga Esquerra de l'Eixample" ...
 $ Codi_carrer                 : int  144601 194202 209900 32700 32700 32700 269902 310008 279600 75101 ...
 $ Nom.carrer                  : chr  "Diagonal" "Mar" "Meridiana" "Balmes" ...
 $ Num_postal.                 : chr  "0361B0361B" "0022 0022" "0595X0595X" "0119 0119" ...
 $ Descripció_dia_setmana      : chr  "Divendres" "Divendres" "Divendres" "Divendres" ...
 $ Dia.setmana                 : chr  "Dv" "Dv" "Dv" "Dv" ...
 $ Descripció.tipus.dia        : chr  "Laboral" "Laboral" "Laboral" "Laboral" ...
 $ NK.Any                      : int  2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 ...
 $ Mes.de.any                  : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Nom.mes                     : chr  "Gener" "Gener" "Gener" "Gener" ...
 $ Dia.de.mes                  : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Descripció.torn             : chr  "Nit" "Nit" "Nit" "Matí" ...
 $ Hora.de.dia                 : int  0 2 5 6 6 6 8 9 16 14 ...
 $ Descripció.causa.vianant    : chr  "No és causa del  vianant" "No és causa del  vianant" "No és causa del  vianant" "No és causa del  vianant" ...
 $ Desc._Tipus_vehicle_implicat: chr  "Taxi" "Motocicleta" "Motocicleta" "Turismo" ...
 $ Descripció_sexe             : chr  "Home" "Home" "Home" "Dona" ...
 $ Edat                        : chr  "41" "19" "24" "29" ...
 $ Descripció_tipus_persona    : chr  "Conductor" "Passatger" "Conductor" "Vianant" ...
 $ Descripció_situació         : chr  "Presentado" "Desconegut" "Presentado" "Desconegut" ...
 $ Descripció_victimització    : chr  "Ferit lleu" "Ferit lleu" "Ferit lleu" "Ferit lleu" ...
 $ Coordenada_UTM_.X.          : num  430142 432161 432262 429716 429716 ...
 $ Coordenada_UTM_.Y.          : num  4583396 4581526 4589064 4582880 4582880 ...
 $ Long                        : num  2.16 2.19 2.19 2.16 2.16 ...
 $ Lat                         : num  41.4 41.4 41.4 41.4 41.4 ...
str(personas2017)
'data.frame':   12148 obs. of  28 variables:
 $ Número_d.expedient          : Factor w/ 9433 levels "2017S000001    ",..: 1 2 3 4 4 5 6 6 7 8 ...
 $ Codi_districte              : int  5 2 2 10 10 1 2 2 3 9 ...
 $ Nom.districte               : Factor w/ 11 levels "Ciutat Vella",..: 11 3 3 9 9 1 3 3 10 8 ...
 $ Codi_barri                  : int  26 5 6 66 66 1 7 7 18 62 ...
 $ Nom_barri                   : Factor w/ 74 levels "Baró de Viver",..: 62 18 41 20 20 24 32 32 66 17 ...
 $ Codi_carrer                 : int  187105 197302 89004 243206 243206 352100 191204 191204 270209 133300 ...
 $ Nom.carrer                  : Factor w/ 1401 levels "","A Zona Franca",..: 755 802 356 970 970 1345 769 769 1070 550 ...
 $ Num_postal.                 : Factor w/ 2004 levels "","0         ",..: 597 836 1756 717 717 65 1310 1310 372 37 ...
 $ Descripció_dia_setmana      : Factor w/ 7 levels "Dijous","Dilluns",..: 6 6 6 6 6 6 6 6 6 6 ...
 $ Dia.setmana                 : Factor w/ 7 levels "Dc","Dg","Dj",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ Descripció.tipus.dia        : Factor w/ 1 level "Laboral": 1 1 1 1 1 1 1 1 1 1 ...
 $ NK.Any                      : int  2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 ...
 $ Mes.de.any                  : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Nom.mes                     : Factor w/ 12 levels "Abril","Agost",..: 5 5 5 5 5 5 5 5 5 5 ...
 $ Dia.de.mes                  : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Descripció.torn             : Factor w/ 3 levels "Matí","Nit","Tarda": 2 2 1 1 1 1 1 1 3 1 ...
 $ Hora.de.dia                 : int  4 2 7 7 7 11 10 10 14 12 ...
 $ Descripció.causa.vianant    : Factor w/ 6 levels "Altres","Creuar per fora pas de vianants",..: 5 5 5 5 5 5 5 5 5 5 ...
 $ Desc._Tipus_vehicle_implicat: Factor w/ 31 levels "Altres vehicles amb motor",..: 31 19 19 13 13 8 19 19 13 3 ...
 $ Descripció_sexe             : Factor w/ 3 levels "Desconegut","Dona",..: 3 3 2 2 3 3 2 3 2 2 ...
 $ Edat                        : Factor w/ 100 levels "0","1","10","11",..: 48 44 22 37 33 60 27 31 31 93 ...
 $ Descripció_tipus_persona    : Factor w/ 3 levels "Conductor","Passatger",..: 1 1 1 2 1 3 2 1 1 2 ...
 $ Descripció_situació         : Factor w/ 6 levels "Altres","Citado",..: 5 5 5 4 5 4 4 5 5 4 ...
 $ Descripció_victimització    : Factor w/ 8 levels "Ferit greu","Ferit greu: hospitalització superior a 24h",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ Coordenada_UTM_.X.          : num  428887 431987 431616 432467 432467 ...
 $ Coordenada_UTM_.Y.          : num  4583659 4583283 4583972 4583327 4583327 ...
 $ Long                        : Factor w/ 6444 levels "'","2.095684",..: 1900 5245 4900 5645 5645 3530 3351 3351 1190 4847 ...
 $ Lat                         : Factor w/ 6386 levels "'","41.322371",..: 3368 2947 3747 2999 2999 1408 2711 2711 991 5291 ...

Juntamos en un unico DataFrame las victimas de 2016 y 2017.

victimas <- rbind(personas2016, personas2017)

Verificamos que se mantengan la estructura y dimensión original.

head(victimas) == head(personas2016)
  Número_d.expedient Codi_districte Nom.districte Codi_barri Nom_barri Codi_carrer Nom.carrer Num_postal.
1               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE        TRUE
2               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE        TRUE
3               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE        TRUE
4               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE        TRUE
5               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE        TRUE
6               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE        TRUE
  Descripció_dia_setmana Dia.setmana Descripció.tipus.dia NK.Any Mes.de.any Nom.mes Dia.de.mes
1                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE       TRUE
2                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE       TRUE
3                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE       TRUE
4                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE       TRUE
5                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE       TRUE
6                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE       TRUE
  Descripció.torn Hora.de.dia Descripció.causa.vianant Desc._Tipus_vehicle_implicat Descripció_sexe Edat
1            TRUE        TRUE                     TRUE                         TRUE            TRUE TRUE
2            TRUE        TRUE                     TRUE                         TRUE            TRUE TRUE
3            TRUE        TRUE                     TRUE                         TRUE            TRUE TRUE
4            TRUE        TRUE                     TRUE                         TRUE            TRUE TRUE
5            TRUE        TRUE                     TRUE                         TRUE            TRUE TRUE
6            TRUE        TRUE                     TRUE                         TRUE            TRUE TRUE
  Descripció_tipus_persona Descripció_situació Descripció_victimització Coordenada_UTM_.X.
1                     TRUE                TRUE                     TRUE               TRUE
2                     TRUE                TRUE                     TRUE               TRUE
3                     TRUE                TRUE                     TRUE               TRUE
4                     TRUE                TRUE                     TRUE               TRUE
5                     TRUE                TRUE                     TRUE               TRUE
6                     TRUE                TRUE                     TRUE               TRUE
  Coordenada_UTM_.Y. Long  Lat
1               TRUE TRUE TRUE
2               TRUE TRUE TRUE
3               TRUE TRUE TRUE
4               TRUE TRUE TRUE
5               TRUE TRUE TRUE
6               TRUE TRUE TRUE
tail(victimas) == tail(personas2017)
      Número_d.expedient Codi_districte Nom.districte Codi_barri Nom_barri Codi_carrer Nom.carrer
24215               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE
24216               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE
24217               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE
24218               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE
24219               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE
24220               TRUE           TRUE          TRUE       TRUE      TRUE        TRUE       TRUE
      Num_postal. Descripció_dia_setmana Dia.setmana Descripció.tipus.dia NK.Any Mes.de.any Nom.mes
24215        TRUE                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE
24216        TRUE                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE
24217        TRUE                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE
24218        TRUE                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE
24219        TRUE                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE
24220        TRUE                   TRUE        TRUE                 TRUE   TRUE       TRUE    TRUE
      Dia.de.mes Descripció.torn Hora.de.dia Descripció.causa.vianant Desc._Tipus_vehicle_implicat
24215       TRUE            TRUE        TRUE                     TRUE                         TRUE
24216       TRUE            TRUE        TRUE                     TRUE                         TRUE
24217       TRUE            TRUE        TRUE                     TRUE                         TRUE
24218       TRUE            TRUE        TRUE                     TRUE                         TRUE
24219       TRUE            TRUE        TRUE                     TRUE                         TRUE
24220       TRUE            TRUE        TRUE                     TRUE                         TRUE
      Descripció_sexe Edat Descripció_tipus_persona Descripció_situació Descripció_victimització
24215            TRUE TRUE                     TRUE                TRUE                     TRUE
24216            TRUE TRUE                     TRUE                TRUE                     TRUE
24217            TRUE TRUE                     TRUE                TRUE                     TRUE
24218            TRUE TRUE                     TRUE                TRUE                     TRUE
24219            TRUE TRUE                     TRUE                TRUE                     TRUE
24220            TRUE TRUE                     TRUE                TRUE                     TRUE
      Coordenada_UTM_.X. Coordenada_UTM_.Y. Long  Lat
24215               TRUE               TRUE TRUE TRUE
24216               TRUE               TRUE TRUE TRUE
24217               TRUE               TRUE TRUE TRUE
24218               TRUE               TRUE TRUE TRUE
24219               TRUE               TRUE TRUE TRUE
24220               TRUE               TRUE TRUE TRUE
dim(victimas)[1] == dim(personas2016)[1] + dim(personas2017)[1]
[1] TRUE
(dim(victimas)[2] == dim(personas2016)[2]) & (dim(victimas)[2] == dim(personas2017)[2])
[1] TRUE

Creamos un DataFrame con las columnas que utilizaremos durante nuestra analisis.

filtro_victimas <- c("Número_d.expedient", 'Nom.districte', 'Descripció_dia_setmana',
       'NK.Any', 'Mes.de.any', 'Dia.de.mes',
       'Descripció.torn', 'Descripció_sexe', 'Edat',
       'Descripció_tipus_persona', 'Descripció_victimització',
       "Coordenada_UTM_.X.", "Coordenada_UTM_.Y.")
victimas <- victimas[filtro_victimas]
head(victimas)

Cambiamos los nombres de las columnas.

names(victimas) <- c('NumExpediente', 'Distrito', 'DiaSemana', 'Ano', 'Mes', 'Dia','Horario', 'Sexo', 'Edad', 'TipoPersona', 'TriajeVictima', 'C_UTM_X', 'C_UTM_Y')
head(victimas)

Vamos a repetir las mismas operaciones con las bases de datos de vehiculos. Para este trabajo vamos a tomar en cuenta el Modelo del vehiculo, la tipología de carnet del conductor y la antiguedad del carnet.

vehiculos2016<- read.csv("2016_accidents_vehicles_gu_bcn_.csv")
head(vehiculos2016)
vehiculos2017<- read.csv("2017_accidents_vehicles_gu_bcn_.csv")
head(vehiculos2017)
dim(vehiculos2016)
[1] 19410    27
dim(vehiculos2017)
[1] 19795    27
str(vehiculos2016)
'data.frame':   19410 obs. of  27 variables:
 $ Codi.d.expedient           : Factor w/ 10139 levels "","2016S000001    ",..: 4656 8623 8623 9868 9868 2187 2187 4034 4034 7966 ...
 $ Codi.districte             : int  5 5 5 5 5 5 5 5 5 5 ...
 $ Nom.districte              : Factor w/ 11 levels "Ciutat Vella",..: 11 11 11 11 11 11 11 11 11 11 ...
 $ Codi.barri                 : int  22 22 22 22 22 22 22 22 22 22 ...
 $ Nom.barri                  : Factor w/ 74 levels "Baró de Viver",..: 72 72 72 72 72 72 72 72 72 72 ...
 $ Codi.carrer                : int  700053 202050 202050 700059 700059 221928 221928 700059 700059 700059 ...
 $ Nom.carrer                 : Factor w/ 1142 levels "A / Número 3                                      ",..: 669 650 650 1097 1097 912 912 1097 1097 1097 ...
 $ Num.postal.caption         : Factor w/ 2001 levels "","0","0000 0000",..: 144 16 16 437 437 166 166 94 94 1938 ...
 $ Descripció.dia.setmana     : Factor w/ 7 levels "Dijous","Dilluns",..: 4 1 1 4 4 5 5 1 1 1 ...
 $ Dia.setmana                : Factor w/ 7 levels "Dc","Dg","Dj",..: 1 3 3 1 1 6 6 3 3 3 ...
 $ Descripció.tipus.dia       : Factor w/ 1 level "Laboral": 1 1 1 1 1 1 1 1 1 1 ...
 $ NK.Any                     : int  2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 ...
 $ Mes.de.any                 : int  6 11 11 12 12 3 3 5 5 10 ...
 $ Nom.mes                    : Factor w/ 12 levels "Abril","Agost",..: 7 10 10 3 3 9 9 8 8 11 ...
 $ Dia.de.mes                 : int  15 10 10 21 21 19 19 26 26 20 ...
 $ Hora.de.dia                : int  11 19 19 18 18 7 7 7 7 7 ...
 $ Descripció.causa.vianant   : Factor w/ 6 levels "Altres","Creuar per fora pas de vianants",..: 5 5 5 5 5 5 5 5 5 2 ...
 $ Descripció.tipus.de.vehicle: Factor w/ 22 levels "","Autobús","Autobús articulado",..: 8 22 22 16 22 7 16 16 22 22 ...
 $ Descripció.model           : Factor w/ 1310 levels ""," ","@125",..: 86 161 691 402 507 1062 414 1007 350 165 ...
 $ Descripció.marca           : Factor w/ 155 levels "","AIYUMO","ALEXANDER DENNIS",..: 116 7 80 57 132 66 140 57 116 57 ...
 $ Descripció.color           : Factor w/ 19 levels "","Altres","Beige",..: 4 4 2 12 4 4 12 5 4 5 ...
 $ Descripció.carnet          : Factor w/ 19 levels "","A","A1","A2",..: 9 6 6 2 6 9 4 2 6 6 ...
 $ Antiguitat.carnet          : Factor w/ 78 levels "","-2","-46",..: 11 12 71 77 23 14 65 11 18 48 ...
 $ Coordenada.UTM..X.         : Factor w/ 6397 levels "423606,83","424249,09",..: 1 2 2 3 3 4 4 5 5 6 ...
 $ Coordenada.UTM..Y.         : Factor w/ 6403 levels "4575151,17","4575187,41",..: 5627 5506 5506 5516 5516 5167 5167 5271 5271 5247 ...
 $ Longitud                   : num  2.08 2.09 2.09 2.09 2.09 ...
 $ Latitut                    : num  41.4 41.4 41.4 41.4 41.4 ...
str(vehiculos2017)
'data.frame':   19795 obs. of  27 variables:
 $ Codi_expedient             : Factor w/ 10305 levels "2017S000001    ",..: 1 2 2 3 4 4 5 5 5 6 ...
 $ Codi_districte             : int  5 2 2 7 2 2 10 10 10 1 ...
 $ Nom_districte              : Factor w/ 11 levels "Ciutat Vella",..: 11 3 3 5 3 3 9 9 9 1 ...
 $ Codi_barri                 : int  26 5 5 33 6 6 66 66 66 1 ...
 $ Nom_barri                  : Factor w/ 74 levels "Baró de Viver",..: 62 18 18 8 41 41 20 20 20 24 ...
 $ Codi_carrer                : int  187105 197302 197302 265402 89004 89004 243206 243206 243206 352100 ...
 $ Nom_carrer                 : Factor w/ 1676 levels "A Zona Franca",..: 882 935 935 1251 421 421 1139 1139 1139 1516 ...
 $ Num_postal.                : Factor w/ 2076 levels "","0         ",..: 624 872 872 3 1818 1818 750 750 750 69 ...
 $ Descripcio_dia_setmana     : Factor w/ 7 levels "Dijous","Dilluns",..: 6 6 6 6 6 6 6 6 6 6 ...
 $ Dia_setmana                : Factor w/ 7 levels "Dc","Dg","Dj",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ Descripcio_tipus_dia       : Factor w/ 1 level "Laboral": 1 1 1 1 1 1 1 1 1 1 ...
 $ NK_Any                     : int  2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 ...
 $ Mes_de_any                 : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Nom_mes                    : Factor w/ 12 levels "Abril","Agost",..: 5 5 5 5 5 5 5 5 5 5 ...
 $ Dia_de_mes                 : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Hora_de_dia                : int  4 2 2 6 7 7 7 7 7 11 ...
 $ Descripcio_causa_vianant   : Factor w/ 6 levels "Altres","Creuar per fora pas de vianants",..: 5 5 5 5 5 5 5 5 5 5 ...
 $ Descripcio_tipus_de_vehicle: Factor w/ 33 levels "Altres vehicles amb motor",..: 33 21 33 33 21 33 13 33 33 8 ...
 $ Descripcio_model           : Factor w/ 1763 levels " ","---","@125",..: 1146 618 1000 167 257 679 1179 65 1028 570 ...
 $ Descripcio_marca           : Factor w/ 185 levels "A U D I","A.U.D.I.",..: 119 76 137 24 96 60 96 115 137 23 ...
 $ Descripcio_color           : Factor w/ 18 levels "Altres","Beige",..: 8 11 8 4 11 8 11 8 4 17 ...
 $ Descripcio_carnet          : Factor w/ 20 levels "A","A1","A2",..: 5 1 12 5 5 5 19 5 12 12 ...
 $ Antiguitat_carnet          : Factor w/ 71 levels "-189","-46","0",..: 17 28 71 26 48 59 70 15 71 71 ...
 $ Coordenada_UTM_.X.         : Factor w/ 7224 levels "","-1","423500,71",..: 2103 5863 5863 3686 5489 5489 6327 6327 6327 3904 ...
 $ Coordenada_UTM_.Y.         : Factor w/ 7234 levels "","-1","4575106,49",..: 3811 3276 3276 5477 4216 4216 3350 3350 3350 1573 ...
 $ Longitud                   : Factor w/ 6968 levels "-1.489619","'",..: 2063 5668 5668 3540 5291 5291 6105 6105 6105 3791 ...
 $ Latitud                    : Factor w/ 6892 levels "-0.001532","'",..: 3607 3165 3165 5180 4017 4017 3217 3217 3217 1532 ...
filtro_vehiculos2016 <- c("Codi.d.expedient", 'Descripció.tipus.de.vehicle', 'Descripció.carnet',
       'Antiguitat.carnet')
vehiculos2016 <- vehiculos2016[filtro_vehiculos2016]
head(vehiculos2016)
filtro_vehiculos2017 <- c("Codi_expedient", 'Descripcio_tipus_de_vehicle', 'Descripcio_carnet',
       'Antiguitat_carnet')
vehiculos2017 <- vehiculos2017[filtro_vehiculos2017]
head(vehiculos2017)
names(vehiculos2016) <- c('NumExpediente', 'Modelo', 'Carnet', 'Antig_carnet')
names(vehiculos2017) <- c('NumExpediente', 'Modelo', 'Carnet', 'Antig_carnet')
vehiculos <- rbind(vehiculos2016, vehiculos2017)
head(vehiculos)
dim(vehiculos)[1] == dim(vehiculos2016)[1] + dim(vehiculos2017)[1]
[1] TRUE
(dim(vehiculos)[2] == dim(vehiculos2016)[2]) & (dim(vehiculos)[2] == dim(vehiculos2017)[2])
[1] TRUE

Ahora limpiamos los datos.

Vamos a estudiar los Modelos de vehículos para revisar que no existan errores de tipeo o que un mismo Modelo este escrito de maneras distintas.

class(vehiculos$Modelo)
[1] "factor"

Como está en factor lo tengo que convertir en character.

vehiculos$Modelo<-as.character(vehiculos$Modelo)

Quiero saber todos los nombres distintos que aparecen en el campo “Modelo”.

unique(vehiculos$Modelo)
 [1] "Camión > 3,5 Tm"              "Turismo"                      "Motocicleta"                 
 [4] "Camión <= 3,5 Tm"             "Bicicleta"                    "Taxi"                        
 [7] "Furgoneta"                    "Ciclomotor"                   "Autobús"                     
[10] "Todo terreno"                 "Autocar"                      "Tranvía o tren"              
[13] "Tractocamión"                 "Maquinaria de obras"          "Otros vehíc. a motor"        
[16] "Carro"                        "Autobús articulado"           "Cuadriciclo <75cc"           
[19] "Autocaravana"                 "Microbus <=17 plazas"         "Cuadriciclo >=75cc"          
[22] ""                             "Turisme"                      "Camió rígid <= 3,5 tones"    
[25] "Autobús articulat"            "Camió rígid > 3,5 tones"      "Tractor camió"               
[28] "Altres vehicles sense motor"  "Altres vehicles amb motor"    "Maquinària d'obres i serveis"
[31] "Tren o tramvia"               "Tot terreny"                  "Quadricicle > 75 cc"         
[34] "Quadricicle < 75 cc"          "Desconegut"                   "Microbus <= 17"              

Aquí podemos observar que hay variables que se repiten porque están escritas de maneras distintas como por ejemplo Cuadriciclo >=75cc = Quadricicle > 75 cc y Turisme = Turismo Por lo que debo normalizar la información.

vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Carro", "Turismo", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Turisme", "Turismo", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Quadricicle > 75 cc", "Cuadriciclo >=75cc", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Tot terreny", "Todo terreno", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Quadricicle < 75 cc", "Cuadriciclo <75cc", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Tractor camió", "Tractocamión", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Microbus <= 17", "Microbus <=17 plazas", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Altres vehicles amb motor", "Otros vehíc. a motor", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Maquinària d'obres i serveis", "Maquinaria de obras", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Camió rígid <= 3,5 tones", "Camión <= 3,5 Tm", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Camió rígid > 3,5 tones", "Camión > 3,5 Tm", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Tren o tramvia", "Tranvía o tren", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Autobús articulat", "Autobús articulado", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "Autocar", "Autobús", vehiculos$Modelo)
vehiculos$Modelo<-ifelse(vehiculos$Modelo == "", "Desconegut", vehiculos$Modelo)

Comprobamos.

unique(vehiculos$Modelo)
 [1] "Camión > 3,5 Tm"             "Turismo"                     "Motocicleta"                
 [4] "Camión <= 3,5 Tm"            "Bicicleta"                   "Taxi"                       
 [7] "Furgoneta"                   "Ciclomotor"                  "Autobús"                    
[10] "Todo terreno"                "Tranvía o tren"              "Tractocamión"               
[13] "Maquinaria de obras"         "Otros vehíc. a motor"        "Autobús articulado"         
[16] "Cuadriciclo <75cc"           "Autocaravana"                "Microbus <=17 plazas"       
[19] "Cuadriciclo >=75cc"          "Desconegut"                  "Altres vehicles sense motor"

Ahora revisamos los tipos de carnet.

class(vehiculos$Carnet)
[1] "factor"

Como está en factor, lo debo convertir en character.

vehiculos$Carnet<-as.character(vehiculos$Carnet)

Quiero saber todos los nombres distintos que aparecen en el campo “Carnet”.

unique(vehiculos$Carnet)
 [1] "C"            "B"            "A"            "A2"           "Desconegut"   "BTP"         
 [7] "A1"           "AM"           "D"            "E C"          "E D"          "Llicència"   
[13] "B1"           "D1"           "C1"           "E B"          "E C1"         ""            
[19] "E D1"         "Es desconeix" "Sense permís"

Los tipos de carnet de conducir que existen en España son: AM, A1, A2, A, B1, B, C1, C, D1, D, BE, C1E, CE, D1E, DE y BTP (ya está descontinuado). Además que hay personas que conducen sin permiso o son las victimas. Tomamos como Licencia a aquellas personas que conducen con permisos extranjeros y esta variable tiene un error de tipeo. También “Desconegut” = “Es desconeix”. Normalizamos esta información.

vehiculos$Carnet<-ifelse(vehiculos$Carnet == "E C", "CE", vehiculos$Carnet)
vehiculos$Carnet<-ifelse(vehiculos$Carnet == "Es desconeix", "Desconegut", vehiculos$Carnet)
vehiculos$Carnet<-ifelse(vehiculos$Carnet == "Llicència", "licencia", vehiculos$Carnet)
vehiculos$Carnet<-ifelse(vehiculos$Carnet == "E D", "DE", vehiculos$Carnet)
vehiculos$Carnet<-ifelse(vehiculos$Carnet == "E C1", "C1E", vehiculos$Carnet)
vehiculos$Carnet<-ifelse(vehiculos$Carnet == "E B", "BE", vehiculos$Carnet)
vehiculos$Carnet<-ifelse(vehiculos$Carnet == "E D1", "D1E", vehiculos$Carnet)
vehiculos$Carnet<-ifelse(vehiculos$Carnet == "", "Desconegut", vehiculos$Carnet)

Comprobamos.

unique(vehiculos$Carnet)
 [1] "C"            "B"            "A"            "A2"           "Desconegut"   "BTP"         
 [7] "A1"           "AM"           "D"            "CE"           "DE"           "licencia"    
[13] "B1"           "D1"           "C1"           "BE"           "C1E"          "D1E"         
[19] "Sense permís"

Realizamos el mismo proceso para verificar la antiguedad de los carnets. Como la antiguedad del carnet no puede ser negativa ni mayor a 100, decimos que es un error a la hora de tomar los datos y lo agrupamos en desconocidos. Pero primero es necesario convertirlo en numerico.

class(vehiculos$Antig_carnet)
[1] "factor"
vehiculos$Antig_carnet<-as.numeric(as.character(vehiculos$Antig_carnet))
NAs introduced by coercion
unique(vehiculos$Antig_carnet)
 [1]   11   12   66    9   21   14    6   18   44   NA   10    0   26   25    7   20    3   22    8    2
[21]   41    4   17   54   24   32    5   15   34   31   29    1   19   33   55   23   46   13   27   52
[41]   30   47   16   39   43   38   35   40   53   36   62   37   64   56   -2   45   28   60   42   48
[61]   51   58   73   49   50   -5   59  -47   57   61   63 1818  -46 -484   67   68 -972   69 -189   71

Limpiamos los datos.

vehiculos$Antig_carnet<-ifelse(vehiculos$Antig_carnet == 0, 0, vehiculos$Antig_carnet)
vehiculos$Antig_carnet<-ifelse(vehiculos$Antig_carnet < 0, NA, vehiculos$Antig_carnet)
vehiculos$Antig_carnet<-ifelse(vehiculos$Antig_carnet > 100, NA, vehiculos$Antig_carnet)

Comprobamos.

unique(vehiculos$Antig_carnet)
 [1] 11 12 66  9 21 14  6 18 44 NA 10  0 26 25  7 20  3 22  8  2 41  4 17 54 24 32  5 15 34 31 29  1 19 33
[35] 55 23 46 13 27 52 30 47 16 39 43 38 35 40 53 36 62 37 64 56 45 28 60 42 48 51 58 73 49 50 59 57 61 63
[69] 67 68 69 71

Procedemos a revisar los distritos y a transformarlos en character.

victimas$Distrito<-as.character(victimas$Distrito)
unique(victimas$Distrito)
 [1] "Eixample"            "Ciutat Vella"        "Nou Barris"          "Horta-Guinardó"     
 [5] "Sarrià-Sant Gervasi" "Sant Martí"          "Sant Andreu"         "Gràcia"             
 [9] "Sants-Montjuïc"      "Les Corts"           "Desconegut"         

En el caso de los distritos no hay nada que modificar.

Revisamos los días de semana.

class(victimas$DiaSemana)
[1] "character"
unique(victimas$DiaSemana)
[1] "Divendres" "Dissabte"  "Diumenge"  "Dilluns"   "Dimecres"  "Dimarts"   "Dijous"   

Tampoco hay nada que transformar en esta columna.

Revisamos que solamente tengamos como año 2016 y 2017 y verificamos que sea numerico.

unique(victimas$Ano)
[1] 2016 2017
class(victimas$Ano)
[1] "integer"

Revisamos que el campo de día de semana tenga sólo valores de 1 a 31 y verificamos que efectivamente sea numerico.

unique(victimas$Dia)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
class(victimas$Dia)
[1] "integer"

Ahora revisamos que el campo de mes tenga sólo valores de 1 a 12 y que sea numerico.

unique(victimas$Mes)
 [1]  1  2  3  4  6  5  9  7  8 10 11 12
class(victimas$Mes)
[1] "integer"

Procedemos a revisar el horario, que se refiere a si ocurrió en la mañana, tarde o noche.

unique(victimas$Horario)
[1] "Nit"   "Matí"  "Tarda"

Revisamos el sexo para verificar que no haya ningun error de tipeo.

unique(victimas$Sexo)
[1] "Home"       "Dona"       "Desconegut"

Comprobamos el tipo las edades de las victimas.

class(victimas$Edad)
[1] "character"

Hay que transformarlo en numerico.

victimas$Edad<-as.integer(victimas$Edad)
NAs introduced by coercion

Vemos las edades de las personas involucradas.

unique(victimas$Edad)
  [1]  41  19  24  29  36  45  68  22  37  27   1  32   9  28  20  21  86  18  23  46  47  79  42   4   7
 [26]  60  26  50  31  44  25  48  30  15  49  78  38  54  53  52  11  51  33  65  90  63  61  62  57  40
 [51]  43  77  NA  39   5  56  74  34  81  64  58  35  17  55  12  59  66   0  72  16  70  71  67   3   2
 [76]   8  80  83  75  76  84  10  73  87  69  13   6  14  82  92  85  89  88  96  94  93  91 119  98 117
[101]  97  95

Tomamos como error las edades mayores a 112 años (que es la persona más vieja de España) y las agrupamos en los desconocidos.

victimas$Edad= ifelse(victimas$Edad > 112, NA, victimas$Edad)

Comprobamos.

unique(victimas$Edad)
  [1] 41 19 24 29 36 45 68 22 37 27  1 32  9 28 20 21 86 18 23 46 47 79 42  4  7 60 26 50 31 44 25 48 30
 [34] 15 49 78 38 54 53 52 11 51 33 65 90 63 61 62 57 40 43 77 NA 39  5 56 74 34 81 64 58 35 17 55 12 59
 [67] 66  0 72 16 70 71 67  3  2  8 80 83 75 76 84 10 73 87 69 13  6 14 82 92 85 89 88 96 94 93 91 98 97
[100] 95

Revisamos el tipo de persona que se refiere al papel de la victima, es decir, si era el conductor, el pasajero, peaton, etc.

unique(victimas$TipoPersona)
[1] "Conductor" "Passatger" "Vianant"  

El triaje se refiere a la gravedad del herido.

unique(victimas$TriajeVictima)
[1] "Ferit lleu"                                              
[2] "Ferit greu"                                              
[3] "Mort"                                                    
[4] "Ferit lleu: Hospitalització fins a 24h"                  
[5] "Ferit greu: hospitalització superior a 24h"              
[6] "Ferit lleu: Amb assistència sanitària en lloc d'accident"
[7] "Ferit lleu: Rebutja assistència sanitària"               
[8] "Mort (dins 24h posteriors accident)"                     

Para el analisis agrupamos en leve, grave y muerto.

victimas$TriajeVictima<-ifelse(victimas$TriajeVictima == "Ferit lleu: Hospitalització fins a 24h", "Ferit lleu", victimas$TriajeVictima)
victimas$TriajeVictima<-ifelse(victimas$TriajeVictima == "Ferit lleu: Amb assistència sanitària en lloc d'accident", "Ferit lleu", victimas$TriajeVictima)
victimas$TriajeVictima<-ifelse(victimas$TriajeVictima == "Ferit lleu: Rebutja assistència sanitària", "Ferit lleu", victimas$TriajeVictima)
victimas$TriajeVictima<-ifelse(victimas$TriajeVictima == "Ferit greu: hospitalització superior a 24h", "Ferit greu", victimas$TriajeVictima)
install.packages("readr")
trying URL 'https://cran.rstudio.com/bin/macosx/el-capitan/contrib/3.5/readr_1.3.1.tgz'
Content type 'application/x-gzip' length 777189 bytes (758 KB)
==================================================
downloaded 758 KB

The downloaded binary packages are in
    /var/folders/dv/s9xmq08d7xj0n3xdzcyv3g8h0000gn/T//RtmpRmBKvi/downloaded_packages
victimas$TriajeVictima<-ifelse(victimas$TriajeVictima == "Mort (dins 24h posteriors accident)", "Mort", victimas$TriajeVictima)

Comprobamos.

unique(victimas$TriajeVictima)
[1] "Ferit lleu" "Ferit greu" "Mort"      

Ya tenemos los datos limpios por lo que procedemos a interpretarlos.

Graficos

Primero instalamos ggplot2 y llamamos a la libreria.

install.packages("ggplot2")
Error in install.packages : Updating loaded packages
library(ggplot2)

Ahora graficamos un histograma con la cantidad de victimas según la edad utilizando en el eje x la escala de 5 años.

ggplot(data=victimas, aes(victimas$Edad)) + 
  geom_histogram(breaks=seq(0, 100, by = 5), 
                 col="red", 
                 aes(fill=..count..)) +
  scale_fill_gradient("Número victimas", low = "green", high = "red") +
labs(title="Histograma número de victimas por edad") +
labs(x="Edad", y="Cantidad")

En este histograma podemos ver una representación gráfica de la cantidad de victimas según la edad. El histograma incluye a su vez un mapa de calor que permite una visualización más rápida. Se puede observar que la mayoria de las victimas se concentran en la edad de 20 a 30 años.

Ahora veremos las estadísticas principales de la edad:

summary(victimas$Edad)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
 0.0000 26.0000 36.0000 38.3065 48.0000 98.0000     174 

La edad mínima de las victimas es de 0, lo que puede implicar que hay niños menores a 1 año involucrados y la edad promedio es de 38 años.

A continuación realizamos un histograma de la cantidad de accidentes según la antiguedad del carnet. Para ello se utiliza en el eje x la escala de 5 años

ggplot(data=vehiculos, aes(vehiculos$Antig_carnet)) + 
  geom_histogram(breaks=seq(0, 70, by = 5), 
                 col="blue", 
                 aes(fill=..count..)) +
  scale_fill_gradient("Número victimas", low = "green", high = "darkblue") +
labs(title="Histograma número de victimas por antiguedad de carnet") +
labs(x="Antiguedad", y="Cantidad")

En este histograma podemos observar como disminuye el número de accidentes al crecer de la antiguedad del carnet de conducir.

Vemos las estadisticas principales de la antiguedad de carnet.

summary(vehiculos$Antig_carnet)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max.     NA's 
 0.00000  6.00000 13.00000 16.91014 26.00000 73.00000     4841 

Ahora instalamos el paquete de Tidyverse para poder utilizar la libreria de dplyr que nos permite analizar y manipular datos en un DataFrame

install.packages("tidyverse")
trying URL 'https://cran.rstudio.com/bin/macosx/el-capitan/contrib/3.5/tidyverse_1.2.1.tgz'
Content type 'application/x-gzip' length 88754 bytes (86 KB)
==================================================
downloaded 86 KB

The downloaded binary packages are in
    /var/folders/dv/s9xmq08d7xj0n3xdzcyv3g8h0000gn/T//RtmpRmBKvi/downloaded_packages
library(dplyr)

Agrupamos por día de semana y graficamos para ver la tendencia.

PorDia<- victimas %>%
    group_by(DiaSemana) %>%
    summarize(Total=n())%>%
    arrange(desc(Total))
PorDia
positions<- c("Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte", "Diumenge" )
ggplot(data.frame(victimas), aes(x=victimas$DiaSemana)) +
  scale_x_discrete(limits= positions, labels=c("Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"))+
  geom_bar()+
labs(title="Histograma número de victimas por día de la semana") +
labs(x="Dias de semana", y="Cantidad")

Con el gráfico anterior podemos observar que los accidentes tienen una tendencia creciente los días de semana, teniendo un pico los días viernes y que estos disminuyen considerablemente los fines de semana, en especial el domingo.

Ahora vamos a graficar los horarios.

pos<- c("Matí", "Tarda", "Nit")
ggplot(data.frame(victimas), aes(x=victimas$Horario)) +
  scale_x_discrete(limits= pos, labels=c("Mañana", "Tarde", "Noche"))+
  geom_bar()+
labs(title="Histograma número de victimas por horario") +
labs(x="Horario", y="Cantidad")

Podemos observar que la mayoría de los accidentes ocurren por la tarde.

Agrupamos los tipos de carnet y por vehiculos.

TipoCarnet<- vehiculos %>%
    group_by(Carnet) %>%
    summarize(Total=n())%>%
    arrange(desc(Total))
TipoCarnet
TipoVehiculo<- vehiculos %>%
    group_by(Modelo) %>%
    summarize(Total=n())%>%
    arrange(desc(Total))
TipoVehiculo

Graficamos para ver la cantidad de accidentes por barrio.

ggplot(data.frame(victimas), aes(x=victimas$Distrito)) +
  geom_bar(col= "blue" ,fill="blue")+
labs(title="Histograma número de victimas por distrito") +
labs(x="Distrito", y="Cantidad")

El distrito con mayor cantidad de accidentes es el Eixample o en castellano, el Ensanche, que es el tiene mayor cantidad de accidentes. Cabe destacar que es el distrito más poblado de Barcelona en terminos relativos y absolutos.

Creamos una tabla para ver la cantidad de accidentes según el día de semana y el horario y lo graficamos en un mapa de calor.

nueva<-victimas %>%
  group_by(DiaSemana, Horario) %>%
  summarize(Total=n())
positions<- c("Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte", "Diumenge")
nueva$Horario <- factor(nueva$Horario, levels = c("Matí", "Tarda", "Nit"), labels=c("Mañana", "Tarde", "Noche"))
ggplot(nueva, aes(x = nueva$DiaSemana, y = nueva$Horario, fill = nueva$Total)) + scale_x_discrete(limits= positions, labels=c("Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo")) + geom_tile() +
  scale_fill_gradient(low = "white", high = "steelblue")+
  labs(x = "Día Semana", y = "Horario", fill = "Número Accidentes", title = "Mapa de calor número de victimas por día de la semana y horario")

Este gráfico nos permite observar que los días con más accidentes son los viernes por la tarde.

Mapas

Nota: para diseñar un punto en un mapa con la libreria cartociudad, hace falta conocer su latitud y longitud. Por este trabajo, decidimos utilizar sólo las bases de datos de 2016 y 2017, que ya contienen los datos de latitud y longitud a parte de las coordenadas UTM, entonces este procedimiento resulta redondante. Decidimos seguir este camino porque las bases de datos de los años anteriores sólo contienen las coordenadas UTM y entonces nos pareció interesante encontrar una solución a este problema.

Creamos un nuevo DataFrame eliminando del DataFrame original las filas con coordenadas nulas o <0.

victimas_sin_coord_nulas <- victimas[(!is.na(victimas$C_UTM_X) & !is.na(victimas$C_UTM_Y) & victimas$C_UTM_X>0 & victimas$C_UTM_Y>0), ]
victimas_sin_coord_nulas[(is.na(victimas_sin_coord_nulas$C_UTM_X) | is.na(victimas_sin_coord_nulas$C_UTM_Y) | victimas_sin_coord_nulas$C_UTM_X<0 | victimas_sin_coord_nulas$C_UTM_Y<0), ]
head(victimas_sin_coord_nulas)

Instalamos los paquetes necesarios y trasformamos las coordenadas UTM en latitud y longitud.

install.packages("sp")
Error in install.packages : Updating loaded packages
library(sp)  # vector data
install.packages("raster")
Error in install.packages : Updating loaded packages
library(raster)  # raster data
install.packages("rgdal")
Error in install.packages : Updating loaded packages
library(rgdal)  # input/output, projections
install.packages("rgeos")
Error in install.packages : Updating loaded packages
library(rgeos)  # geometry ops
utmcoor<-SpatialPoints(victimas_sin_coord_nulas[, c("C_UTM_X", "C_UTM_Y")], proj4string=CRS("+proj=utm +zone=31"))
longlatcoor<-spTransform(utmcoor,CRS("+proj=longlat"))
head(longlatcoor)
class       : SpatialPoints 
features    : 1 
extent      : 2.164305145, 2.164305145, 41.39906949, 41.39906949  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84 

Añadimos los campos de latitud y longitud al DataFrame. Nos damos cuenta que hay un error en los valores de las coordenadas UTM que genera un deslizamiento de los puntos en el mapa. Afortunadamente, para arreglar este error es suficiente restar a latitud y longitud unos valores fijos.

victimas_sin_coord_nulas$Long <- longlatcoor$C_UTM_X-0.001103145
victimas_sin_coord_nulas$Lat <- longlatcoor$C_UTM_Y-0.00184649
head(victimas_sin_coord_nulas)

Diseñamos en el mapa todos los puntos donde se haya tenido victimas de accidentes durante los años 2016 y 2017.

install.packages("devtools")
Error in install.packages : Updating loaded packages
library(devtools)
install_github("rOpenSpain/caRtociudad")
Skipping install of 'caRtociudad' from a github remote, the SHA1 (a3509700) has not changed since last install.
  Use `force = TRUE` to force installation
library(caRtociudad)
install.packages("ggmap")
Error in install.packages : Updating loaded packages
library(ggmap)
bcn <- cartociudad_geocode("barcelona")
mapa_bcn <- cartociudad_get_map(c(bcn$lat, bcn$lng), 2)
mapa <- ggmap::ggmap(mapa_bcn)
mapa + geom_point(aes(x = Long, y = Lat), data = victimas_sin_coord_nulas, size = 1)

LS0tCnRpdGxlOiAiQUNDSURFTlRFUyBERSBUUsOBRklDTyBFTiBCQVJDRUxPTkEiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCipFbCBvYmpldGl2byBkZSBlc3RlIHRyYWJham8gZXMgYW5hbGl6YXIgYSB0cmF2w6lzIGRlIHRhYmxhcyB5IGdyw6FmaWNvcyBsb3MgcGVyZmlsZXMgKGVkYWQgeSBzZXhvKSBkZSBsYXMgcGVyc29uYXMgcXVlIG3DoXMgZXN0w6FuIGludm9sdWNyYWRhcyBlbiBhY2NpZGVudGVzIGRlIHRyw6FmaWNvIHkgdmlzdWFsaXphciBhIHRyYXbDqXMgZGUgdW4gbWFwYSBsYSBsb2NhbGl6YWNpw7NuIGRlIGxvcyBhY2NpZGVudGVzIHF1ZSBoYW4gY2F1c2FkbyBsYSBtdWVydGUgZGUgbGFzIHbDrWN0aW1hcy4gTG9zIGRhdG9zIGxvcyBkZXNjYXJnYW1vcyBkZSBsYSBww6Fnw61uYSBkZWwgYXl1bnRhbWllbnRvIGRlIEJhcmNlbG9uYSBkZSBsb3MgYcOxb3MgMjAxNiB5IDIwMTcgZSBpbnZvbHVjcmFuIGRvcyBhcmNoaXZvcyBDU1Y6IFBlcnNvbmFzIGludm9sdWNyYWRhcyB5IFZlaMOtY3Vsb3MuKgoKIyMgSW1wb3J0YWNpw7NuIHkgbGltcGllemEgZGUgZGF0b3MgIAoKSW1wb3J0YW1vcyBsb3MgYXJjaGl2b3MgY2N2cyBkZSBwZXJzb25hcyBpbnZvbHVjcmFkYXMgeSB2ZW1vcyBsYXMgcHJpbWVyYXMgNSBsw61uZWFzLgpFbiBlbCBjYXNvIGRlIGxhcyBjb29yZGVuYWRhcywgYWwgaW1wb3J0YXJsYXMgZGUgZm9ybWEgc3RhbmRhcmQgc2UgZWxpbWluYWJhbiBsb3MgZGVjaW1hbGVzLCBlcyBwb3IgZXN0byBxdWUgdHV2aW1vcyBxdWUgY2FtYmlhciBsYSAsIHBvciAuIHkgbHVlZ28gY29udmVydGlyIGVsIGNhbXBvIGVuIG51bWVyaWNvLiAgCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygicmVhZHIiKQoKbGlicmFyeShyZWFkcikKCmRlbGltID0gIiwiCmRlYyA9ICIsIgpwZXJzb25hczIwMTYgPC0gcmVhZC5jc3YoIjIwMTZfYWNjaWRlbnRzX3BlcnNvbmVzX2d1X2Jjbi5jc3YiLCBoZWFkZXI9VFJVRSwgc2VwPWRlbGltLCBkZWM9ZGVjLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQpjbGFzcyhwZXJzb25hczIwMTYkQ29vcmRlbmFkYV9VVE1fLlguKQpvcHRpb25zKGRpZ2l0cz0xMCkKcGVyc29uYXMyMDE2JENvb3JkZW5hZGFfVVRNXy5YLiA8LSAoZ3N1YigiLCIsICIuIiwgYXMuY2hhcmFjdGVyKHBlcnNvbmFzMjAxNiRDb29yZGVuYWRhX1VUTV8uWC4pKSkKcGVyc29uYXMyMDE2JENvb3JkZW5hZGFfVVRNXy5YLiA8LSBhcy5udW1lcmljKHBlcnNvbmFzMjAxNiRDb29yZGVuYWRhX1VUTV8uWC4pCnBlcnNvbmFzMjAxNiRDb29yZGVuYWRhX1VUTV8uWS4gPC0gKGdzdWIoIiwiLCAiLiIsIGFzLmNoYXJhY3RlcihwZXJzb25hczIwMTYkQ29vcmRlbmFkYV9VVE1fLlkuKSkpCnBlcnNvbmFzMjAxNiRDb29yZGVuYWRhX1VUTV8uWS4gPC0gYXMubnVtZXJpYyhwZXJzb25hczIwMTYkQ29vcmRlbmFkYV9VVE1fLlkuKQpoZWFkKHBlcnNvbmFzMjAxNikKCnBlcnNvbmFzMjAxNzwtIHJlYWQuY3N2KCIyMDE3X2FjY2lkZW50c19wZXJzb25lc19ndV9iY25fLmNzdiIsIGhlYWRlcj0gVFJVRSwgc2VwPSIsIikKaGVhZChwZXJzb25hczIwMTcpCmNsYXNzKHBlcnNvbmFzMjAxNyRDb29yZGVuYWRhX1VUTV8uWC4pCm9wdGlvbnMoZGlnaXRzPTEwKQpwZXJzb25hczIwMTckQ29vcmRlbmFkYV9VVE1fLlguPC0gKGdzdWIoIiwiLCAiLiIsIGFzLmNoYXJhY3RlcihwZXJzb25hczIwMTckQ29vcmRlbmFkYV9VVE1fLlguKSkpCnBlcnNvbmFzMjAxNyRDb29yZGVuYWRhX1VUTV8uWC4gPC0gYXMubnVtZXJpYyhwZXJzb25hczIwMTckQ29vcmRlbmFkYV9VVE1fLlguKQpwZXJzb25hczIwMTckQ29vcmRlbmFkYV9VVE1fLlkuIDwtIChnc3ViKCIsIiwgIi4iLCBhcy5jaGFyYWN0ZXIocGVyc29uYXMyMDE3JENvb3JkZW5hZGFfVVRNXy5ZLikpKQpwZXJzb25hczIwMTckQ29vcmRlbmFkYV9VVE1fLlkuIDwtIGFzLm51bWVyaWMocGVyc29uYXMyMDE3JENvb3JkZW5hZGFfVVRNXy5ZLikKaGVhZChwZXJzb25hczIwMTcpCmBgYAoKCkVzdHVkaWFtb3MgbGEgZXN0cnVjdHVyYSB5IGRpbWVuc2nDs24gZGUgbG9zIGRvcyBEYXRhRnJhbWVzLiAgCgpgYGB7cn0KZGltKHBlcnNvbmFzMjAxNikKZGltKHBlcnNvbmFzMjAxNykKc3RyKHBlcnNvbmFzMjAxNikKc3RyKHBlcnNvbmFzMjAxNykKYGBgCgoKSnVudGFtb3MgZW4gdW4gdW5pY28gRGF0YUZyYW1lIGxhcyB2aWN0aW1hcyBkZSAyMDE2IHkgMjAxNy4gIAoKYGBge3J9CnZpY3RpbWFzIDwtIHJiaW5kKHBlcnNvbmFzMjAxNiwgcGVyc29uYXMyMDE3KQpgYGAKCgpWZXJpZmljYW1vcyBxdWUgc2UgbWFudGVuZ2FuIGxhIGVzdHJ1Y3R1cmEgeSBkaW1lbnNpw7NuIG9yaWdpbmFsLiAgCgpgYGB7cn0KaGVhZCh2aWN0aW1hcykgPT0gaGVhZChwZXJzb25hczIwMTYpCnRhaWwodmljdGltYXMpID09IHRhaWwocGVyc29uYXMyMDE3KQpkaW0odmljdGltYXMpWzFdID09IGRpbShwZXJzb25hczIwMTYpWzFdICsgZGltKHBlcnNvbmFzMjAxNylbMV0KKGRpbSh2aWN0aW1hcylbMl0gPT0gZGltKHBlcnNvbmFzMjAxNilbMl0pICYgKGRpbSh2aWN0aW1hcylbMl0gPT0gZGltKHBlcnNvbmFzMjAxNylbMl0pCmBgYAoKCkNyZWFtb3MgdW4gRGF0YUZyYW1lIGNvbiBsYXMgY29sdW1uYXMgcXVlIHV0aWxpemFyZW1vcyBkdXJhbnRlIG51ZXN0cmEgYW5hbGlzaXMuCgpgYGB7cn0KZmlsdHJvX3ZpY3RpbWFzIDwtIGMoIk7Dum1lcm9fZC5leHBlZGllbnQiLCAnTm9tLmRpc3RyaWN0ZScsICdEZXNjcmlwY2nDs19kaWFfc2V0bWFuYScsCiAgICAgICAnTksuQW55JywgJ01lcy5kZS5hbnknLCAnRGlhLmRlLm1lcycsCiAgICAgICAnRGVzY3JpcGNpw7MudG9ybicsICdEZXNjcmlwY2nDs19zZXhlJywgJ0VkYXQnLAogICAgICAgJ0Rlc2NyaXBjacOzX3RpcHVzX3BlcnNvbmEnLCAnRGVzY3JpcGNpw7NfdmljdGltaXR6YWNpw7MnLAogICAgICAgIkNvb3JkZW5hZGFfVVRNXy5YLiIsICJDb29yZGVuYWRhX1VUTV8uWS4iKQp2aWN0aW1hcyA8LSB2aWN0aW1hc1tmaWx0cm9fdmljdGltYXNdCmhlYWQodmljdGltYXMpCmBgYAoKCkNhbWJpYW1vcyBsb3Mgbm9tYnJlcyBkZSBsYXMgY29sdW1uYXMuCgpgYGB7cn0KbmFtZXModmljdGltYXMpIDwtIGMoJ051bUV4cGVkaWVudGUnLCAnRGlzdHJpdG8nLCAnRGlhU2VtYW5hJywgJ0FubycsICdNZXMnLCAnRGlhJywnSG9yYXJpbycsICdTZXhvJywgJ0VkYWQnLCAnVGlwb1BlcnNvbmEnLCAnVHJpYWplVmljdGltYScsICdDX1VUTV9YJywgJ0NfVVRNX1knKQpoZWFkKHZpY3RpbWFzKQpgYGAKCgpWYW1vcyBhIHJlcGV0aXIgbGFzIG1pc21hcyBvcGVyYWNpb25lcyBjb24gbGFzIGJhc2VzIGRlIGRhdG9zIGRlIHZlaGljdWxvcy4gUGFyYSBlc3RlIHRyYWJham8gdmFtb3MgYSB0b21hciBlbiBjdWVudGEgZWwgTW9kZWxvIGRlbCB2ZWhpY3VsbywgbGEgdGlwb2xvZ8OtYSBkZSBjYXJuZXQgZGVsIGNvbmR1Y3RvciB5IGxhIGFudGlndWVkYWQgZGVsIGNhcm5ldC4KCmBgYHtyfQp2ZWhpY3Vsb3MyMDE2PC0gcmVhZC5jc3YoIjIwMTZfYWNjaWRlbnRzX3ZlaGljbGVzX2d1X2Jjbl8uY3N2IikKaGVhZCh2ZWhpY3Vsb3MyMDE2KQp2ZWhpY3Vsb3MyMDE3PC0gcmVhZC5jc3YoIjIwMTdfYWNjaWRlbnRzX3ZlaGljbGVzX2d1X2Jjbl8uY3N2IikKaGVhZCh2ZWhpY3Vsb3MyMDE3KQoKZGltKHZlaGljdWxvczIwMTYpCmRpbSh2ZWhpY3Vsb3MyMDE3KQpzdHIodmVoaWN1bG9zMjAxNikKc3RyKHZlaGljdWxvczIwMTcpCgpmaWx0cm9fdmVoaWN1bG9zMjAxNiA8LSBjKCJDb2RpLmQuZXhwZWRpZW50IiwgJ0Rlc2NyaXBjacOzLnRpcHVzLmRlLnZlaGljbGUnLCAnRGVzY3JpcGNpw7MuY2FybmV0JywKICAgICAgICdBbnRpZ3VpdGF0LmNhcm5ldCcpCnZlaGljdWxvczIwMTYgPC0gdmVoaWN1bG9zMjAxNltmaWx0cm9fdmVoaWN1bG9zMjAxNl0KaGVhZCh2ZWhpY3Vsb3MyMDE2KQoKZmlsdHJvX3ZlaGljdWxvczIwMTcgPC0gYygiQ29kaV9leHBlZGllbnQiLCAnRGVzY3JpcGNpb190aXB1c19kZV92ZWhpY2xlJywgJ0Rlc2NyaXBjaW9fY2FybmV0JywKICAgICAgICdBbnRpZ3VpdGF0X2Nhcm5ldCcpCnZlaGljdWxvczIwMTcgPC0gdmVoaWN1bG9zMjAxN1tmaWx0cm9fdmVoaWN1bG9zMjAxN10KaGVhZCh2ZWhpY3Vsb3MyMDE3KQoKbmFtZXModmVoaWN1bG9zMjAxNikgPC0gYygnTnVtRXhwZWRpZW50ZScsICdNb2RlbG8nLCAnQ2FybmV0JywgJ0FudGlnX2Nhcm5ldCcpCm5hbWVzKHZlaGljdWxvczIwMTcpIDwtIGMoJ051bUV4cGVkaWVudGUnLCAnTW9kZWxvJywgJ0Nhcm5ldCcsICdBbnRpZ19jYXJuZXQnKQoKdmVoaWN1bG9zIDwtIHJiaW5kKHZlaGljdWxvczIwMTYsIHZlaGljdWxvczIwMTcpCgpoZWFkKHZlaGljdWxvcykKCmRpbSh2ZWhpY3Vsb3MpWzFdID09IGRpbSh2ZWhpY3Vsb3MyMDE2KVsxXSArIGRpbSh2ZWhpY3Vsb3MyMDE3KVsxXQooZGltKHZlaGljdWxvcylbMl0gPT0gZGltKHZlaGljdWxvczIwMTYpWzJdKSAmIChkaW0odmVoaWN1bG9zKVsyXSA9PSBkaW0odmVoaWN1bG9zMjAxNylbMl0pCmBgYAoKCkFob3JhIGxpbXBpYW1vcyBsb3MgZGF0b3MuCgoKVmFtb3MgYSBlc3R1ZGlhciBsb3MgTW9kZWxvcyBkZSB2ZWjDrWN1bG9zIHBhcmEgcmV2aXNhciBxdWUgbm8gZXhpc3RhbiBlcnJvcmVzIGRlIHRpcGVvIG8gcXVlIHVuIG1pc21vIE1vZGVsbyBlc3RlIGVzY3JpdG8gZGUgbWFuZXJhcyBkaXN0aW50YXMuCgpgYGB7cn0KY2xhc3ModmVoaWN1bG9zJE1vZGVsbykKYGBgCgoKQ29tbyBlc3TDoSBlbiBmYWN0b3IgbG8gdGVuZ28gcXVlIGNvbnZlcnRpciBlbiBjaGFyYWN0ZXIuCgpgYGB7cn0KdmVoaWN1bG9zJE1vZGVsbzwtYXMuY2hhcmFjdGVyKHZlaGljdWxvcyRNb2RlbG8pCmBgYAoKClF1aWVybyBzYWJlciB0b2RvcyBsb3Mgbm9tYnJlcyBkaXN0aW50b3MgcXVlIGFwYXJlY2VuIGVuIGVsIGNhbXBvICJNb2RlbG8iLgoKYGBge3J9CnVuaXF1ZSh2ZWhpY3Vsb3MkTW9kZWxvKQpgYGAKCgpBcXXDrSBwb2RlbW9zIG9ic2VydmFyIHF1ZSBoYXkgdmFyaWFibGVzIHF1ZSBzZSByZXBpdGVuIHBvcnF1ZSBlc3TDoW4gZXNjcml0YXMgZGUgbWFuZXJhcyBkaXN0aW50YXMgY29tbyBwb3IgZWplbXBsbyBDdWFkcmljaWNsbyA+PTc1Y2MgPSBRdWFkcmljaWNsZSA+IDc1IGNjIHkgVHVyaXNtZSA9IFR1cmlzbW8gUG9yIGxvIHF1ZSBkZWJvIG5vcm1hbGl6YXIgbGEgaW5mb3JtYWNpw7NuLgoKYGBge3J9CnZlaGljdWxvcyRNb2RlbG88LWlmZWxzZSh2ZWhpY3Vsb3MkTW9kZWxvID09ICJDYXJybyIsICJUdXJpc21vIiwgdmVoaWN1bG9zJE1vZGVsbykKdmVoaWN1bG9zJE1vZGVsbzwtaWZlbHNlKHZlaGljdWxvcyRNb2RlbG8gPT0gIlR1cmlzbWUiLCAiVHVyaXNtbyIsIHZlaGljdWxvcyRNb2RlbG8pCnZlaGljdWxvcyRNb2RlbG88LWlmZWxzZSh2ZWhpY3Vsb3MkTW9kZWxvID09ICJRdWFkcmljaWNsZSA+IDc1IGNjIiwgIkN1YWRyaWNpY2xvID49NzVjYyIsIHZlaGljdWxvcyRNb2RlbG8pCnZlaGljdWxvcyRNb2RlbG88LWlmZWxzZSh2ZWhpY3Vsb3MkTW9kZWxvID09ICJUb3QgdGVycmVueSIsICJUb2RvIHRlcnJlbm8iLCB2ZWhpY3Vsb3MkTW9kZWxvKQp2ZWhpY3Vsb3MkTW9kZWxvPC1pZmVsc2UodmVoaWN1bG9zJE1vZGVsbyA9PSAiUXVhZHJpY2ljbGUgPCA3NSBjYyIsICJDdWFkcmljaWNsbyA8NzVjYyIsIHZlaGljdWxvcyRNb2RlbG8pCnZlaGljdWxvcyRNb2RlbG88LWlmZWxzZSh2ZWhpY3Vsb3MkTW9kZWxvID09ICJUcmFjdG9yIGNhbWnDsyIsICJUcmFjdG9jYW1pw7NuIiwgdmVoaWN1bG9zJE1vZGVsbykKdmVoaWN1bG9zJE1vZGVsbzwtaWZlbHNlKHZlaGljdWxvcyRNb2RlbG8gPT0gIk1pY3JvYnVzIDw9IDE3IiwgIk1pY3JvYnVzIDw9MTcgcGxhemFzIiwgdmVoaWN1bG9zJE1vZGVsbykKdmVoaWN1bG9zJE1vZGVsbzwtaWZlbHNlKHZlaGljdWxvcyRNb2RlbG8gPT0gIkFsdHJlcyB2ZWhpY2xlcyBhbWIgbW90b3IiLCAiT3Ryb3MgdmVow61jLiBhIG1vdG9yIiwgdmVoaWN1bG9zJE1vZGVsbykKdmVoaWN1bG9zJE1vZGVsbzwtaWZlbHNlKHZlaGljdWxvcyRNb2RlbG8gPT0gIk1hcXVpbsOgcmlhIGQnb2JyZXMgaSBzZXJ2ZWlzIiwgIk1hcXVpbmFyaWEgZGUgb2JyYXMiLCB2ZWhpY3Vsb3MkTW9kZWxvKQp2ZWhpY3Vsb3MkTW9kZWxvPC1pZmVsc2UodmVoaWN1bG9zJE1vZGVsbyA9PSAiQ2FtacOzIHLDrWdpZCA8PSAzLDUgdG9uZXMiLCAiQ2FtacOzbiA8PSAzLDUgVG0iLCB2ZWhpY3Vsb3MkTW9kZWxvKQp2ZWhpY3Vsb3MkTW9kZWxvPC1pZmVsc2UodmVoaWN1bG9zJE1vZGVsbyA9PSAiQ2FtacOzIHLDrWdpZCA+IDMsNSB0b25lcyIsICJDYW1pw7NuID4gMyw1IFRtIiwgdmVoaWN1bG9zJE1vZGVsbykKdmVoaWN1bG9zJE1vZGVsbzwtaWZlbHNlKHZlaGljdWxvcyRNb2RlbG8gPT0gIlRyZW4gbyB0cmFtdmlhIiwgIlRyYW52w61hIG8gdHJlbiIsIHZlaGljdWxvcyRNb2RlbG8pCnZlaGljdWxvcyRNb2RlbG88LWlmZWxzZSh2ZWhpY3Vsb3MkTW9kZWxvID09ICJBdXRvYsO6cyBhcnRpY3VsYXQiLCAiQXV0b2LDunMgYXJ0aWN1bGFkbyIsIHZlaGljdWxvcyRNb2RlbG8pCnZlaGljdWxvcyRNb2RlbG88LWlmZWxzZSh2ZWhpY3Vsb3MkTW9kZWxvID09ICJBdXRvY2FyIiwgIkF1dG9iw7pzIiwgdmVoaWN1bG9zJE1vZGVsbykKdmVoaWN1bG9zJE1vZGVsbzwtaWZlbHNlKHZlaGljdWxvcyRNb2RlbG8gPT0gIiIsICJEZXNjb25lZ3V0IiwgdmVoaWN1bG9zJE1vZGVsbykKYGBgCgoKQ29tcHJvYmFtb3MuCgpgYGB7cn0KdW5pcXVlKHZlaGljdWxvcyRNb2RlbG8pCmBgYAoKCkFob3JhIHJldmlzYW1vcyBsb3MgdGlwb3MgZGUgY2FybmV0LgoKYGBge3J9CmNsYXNzKHZlaGljdWxvcyRDYXJuZXQpCmBgYAoKCkNvbW8gZXN0w6EgZW4gZmFjdG9yLCBsbyBkZWJvIGNvbnZlcnRpciBlbiBjaGFyYWN0ZXIuCgpgYGB7cn0KdmVoaWN1bG9zJENhcm5ldDwtYXMuY2hhcmFjdGVyKHZlaGljdWxvcyRDYXJuZXQpCmBgYAoKClF1aWVybyBzYWJlciB0b2RvcyBsb3Mgbm9tYnJlcyBkaXN0aW50b3MgcXVlIGFwYXJlY2VuIGVuIGVsIGNhbXBvICJDYXJuZXQiLgoKYGBge3J9CnVuaXF1ZSh2ZWhpY3Vsb3MkQ2FybmV0KQpgYGAKCgpMb3MgdGlwb3MgZGUgY2FybmV0IGRlIGNvbmR1Y2lyIHF1ZSBleGlzdGVuIGVuIEVzcGHDsWEgc29uOiBBTSwgQTEsIEEyLCBBLCBCMSwgQiwgQzEsIEMsIEQxLCBELCBCRSwgQzFFLCBDRSwgRDFFLCBERSB5IEJUUCAoeWEgZXN0w6EgZGVzY29udGludWFkbykuIEFkZW3DoXMgcXVlIGhheSBwZXJzb25hcyBxdWUgY29uZHVjZW4gc2luIHBlcm1pc28gbyBzb24gbGFzIHZpY3RpbWFzLiAKVG9tYW1vcyBjb21vIExpY2VuY2lhIGEgYXF1ZWxsYXMgcGVyc29uYXMgcXVlIGNvbmR1Y2VuIGNvbiBwZXJtaXNvcyBleHRyYW5qZXJvcyB5IGVzdGEgdmFyaWFibGUgdGllbmUgdW4gZXJyb3IgZGUgdGlwZW8uIFRhbWJpw6luICJEZXNjb25lZ3V0IiA9ICJFcyBkZXNjb25laXgiLgpOb3JtYWxpemFtb3MgZXN0YSBpbmZvcm1hY2nDs24uCgpgYGB7cn0KdmVoaWN1bG9zJENhcm5ldDwtaWZlbHNlKHZlaGljdWxvcyRDYXJuZXQgPT0gIkUgQyIsICJDRSIsIHZlaGljdWxvcyRDYXJuZXQpCnZlaGljdWxvcyRDYXJuZXQ8LWlmZWxzZSh2ZWhpY3Vsb3MkQ2FybmV0ID09ICJFcyBkZXNjb25laXgiLCAiRGVzY29uZWd1dCIsIHZlaGljdWxvcyRDYXJuZXQpCnZlaGljdWxvcyRDYXJuZXQ8LWlmZWxzZSh2ZWhpY3Vsb3MkQ2FybmV0ID09ICJMbGljw6huY2lhIiwgImxpY2VuY2lhIiwgdmVoaWN1bG9zJENhcm5ldCkKdmVoaWN1bG9zJENhcm5ldDwtaWZlbHNlKHZlaGljdWxvcyRDYXJuZXQgPT0gIkUgRCIsICJERSIsIHZlaGljdWxvcyRDYXJuZXQpCnZlaGljdWxvcyRDYXJuZXQ8LWlmZWxzZSh2ZWhpY3Vsb3MkQ2FybmV0ID09ICJFIEMxIiwgIkMxRSIsIHZlaGljdWxvcyRDYXJuZXQpCnZlaGljdWxvcyRDYXJuZXQ8LWlmZWxzZSh2ZWhpY3Vsb3MkQ2FybmV0ID09ICJFIEIiLCAiQkUiLCB2ZWhpY3Vsb3MkQ2FybmV0KQp2ZWhpY3Vsb3MkQ2FybmV0PC1pZmVsc2UodmVoaWN1bG9zJENhcm5ldCA9PSAiRSBEMSIsICJEMUUiLCB2ZWhpY3Vsb3MkQ2FybmV0KQp2ZWhpY3Vsb3MkQ2FybmV0PC1pZmVsc2UodmVoaWN1bG9zJENhcm5ldCA9PSAiIiwgIkRlc2NvbmVndXQiLCB2ZWhpY3Vsb3MkQ2FybmV0KQpgYGAKCgpDb21wcm9iYW1vcy4KCmBgYHtyfQp1bmlxdWUodmVoaWN1bG9zJENhcm5ldCkKYGBgCgoKUmVhbGl6YW1vcyBlbCBtaXNtbyBwcm9jZXNvIHBhcmEgdmVyaWZpY2FyIGxhIGFudGlndWVkYWQgZGUgbG9zIGNhcm5ldHMuCkNvbW8gbGEgYW50aWd1ZWRhZCBkZWwgY2FybmV0IG5vIHB1ZWRlIHNlciBuZWdhdGl2YSBuaSBtYXlvciBhIDEwMCwgZGVjaW1vcyBxdWUgZXMgdW4gZXJyb3IgYSBsYSBob3JhIGRlIHRvbWFyIGxvcyBkYXRvcyB5IGxvIGFncnVwYW1vcyBlbiBkZXNjb25vY2lkb3MuIFBlcm8gcHJpbWVybyBlcyBuZWNlc2FyaW8gY29udmVydGlybG8gZW4gbnVtZXJpY28uCgpgYGB7cn0KY2xhc3ModmVoaWN1bG9zJEFudGlnX2Nhcm5ldCkKdmVoaWN1bG9zJEFudGlnX2Nhcm5ldDwtYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIodmVoaWN1bG9zJEFudGlnX2Nhcm5ldCkpCnVuaXF1ZSh2ZWhpY3Vsb3MkQW50aWdfY2FybmV0KQpgYGAKCgpMaW1waWFtb3MgbG9zIGRhdG9zLgoKYGBge3J9CnZlaGljdWxvcyRBbnRpZ19jYXJuZXQ8LWlmZWxzZSh2ZWhpY3Vsb3MkQW50aWdfY2FybmV0ID09IDAsIDAsIHZlaGljdWxvcyRBbnRpZ19jYXJuZXQpCnZlaGljdWxvcyRBbnRpZ19jYXJuZXQ8LWlmZWxzZSh2ZWhpY3Vsb3MkQW50aWdfY2FybmV0IDwgMCwgTkEsIHZlaGljdWxvcyRBbnRpZ19jYXJuZXQpCnZlaGljdWxvcyRBbnRpZ19jYXJuZXQ8LWlmZWxzZSh2ZWhpY3Vsb3MkQW50aWdfY2FybmV0ID4gMTAwLCBOQSwgdmVoaWN1bG9zJEFudGlnX2Nhcm5ldCkKYGBgCgoKQ29tcHJvYmFtb3MuCgpgYGB7cn0KdW5pcXVlKHZlaGljdWxvcyRBbnRpZ19jYXJuZXQpCmBgYAoKClByb2NlZGVtb3MgYSByZXZpc2FyIGxvcyBkaXN0cml0b3MgeSBhIHRyYW5zZm9ybWFybG9zIGVuIGNoYXJhY3Rlci4KCmBgYHtyfQp2aWN0aW1hcyREaXN0cml0bzwtYXMuY2hhcmFjdGVyKHZpY3RpbWFzJERpc3RyaXRvKQpgYGAKCmBgYHtyfQp1bmlxdWUodmljdGltYXMkRGlzdHJpdG8pCmBgYAoKRW4gZWwgY2FzbyBkZSBsb3MgZGlzdHJpdG9zIG5vIGhheSBuYWRhIHF1ZSBtb2RpZmljYXIuCgoKUmV2aXNhbW9zIGxvcyBkw61hcyBkZSBzZW1hbmEuCgpgYGB7cn0KY2xhc3ModmljdGltYXMkRGlhU2VtYW5hKQp1bmlxdWUodmljdGltYXMkRGlhU2VtYW5hKQpgYGAKClRhbXBvY28gaGF5IG5hZGEgcXVlIHRyYW5zZm9ybWFyIGVuIGVzdGEgY29sdW1uYS4gCgoKUmV2aXNhbW9zIHF1ZSBzb2xhbWVudGUgdGVuZ2Ftb3MgY29tbyBhw7FvIDIwMTYgeSAyMDE3IHkgdmVyaWZpY2Ftb3MgcXVlIHNlYSBudW1lcmljby4KCmBgYHtyfQp1bmlxdWUodmljdGltYXMkQW5vKQpjbGFzcyh2aWN0aW1hcyRBbm8pCmBgYAoKClJldmlzYW1vcyBxdWUgZWwgY2FtcG8gZGUgZMOtYSBkZSBzZW1hbmEgdGVuZ2Egc8OzbG8gdmFsb3JlcyBkZSAxIGEgMzEgeSB2ZXJpZmljYW1vcyBxdWUgZWZlY3RpdmFtZW50ZSBzZWEgbnVtZXJpY28uCgpgYGB7cn0KdW5pcXVlKHZpY3RpbWFzJERpYSkKY2xhc3ModmljdGltYXMkRGlhKQpgYGAKCgpBaG9yYSByZXZpc2Ftb3MgcXVlIGVsIGNhbXBvIGRlIG1lcyB0ZW5nYSBzw7NsbyB2YWxvcmVzIGRlIDEgYSAxMiB5IHF1ZSBzZWEgbnVtZXJpY28uCgpgYGB7cn0KdW5pcXVlKHZpY3RpbWFzJE1lcykKY2xhc3ModmljdGltYXMkTWVzKQpgYGAKCgpQcm9jZWRlbW9zIGEgcmV2aXNhciBlbCBob3JhcmlvLCBxdWUgc2UgcmVmaWVyZSBhIHNpIG9jdXJyacOzIGVuIGxhIG1hw7FhbmEsIHRhcmRlIG8gbm9jaGUuCgpgYGB7cn0KdW5pcXVlKHZpY3RpbWFzJEhvcmFyaW8pCmBgYAoKClJldmlzYW1vcyBlbCBzZXhvIHBhcmEgdmVyaWZpY2FyIHF1ZSBubyBoYXlhIG5pbmd1biBlcnJvciBkZSB0aXBlby4KCmBgYHtyfQp1bmlxdWUodmljdGltYXMkU2V4bykKYGBgCgoKQ29tcHJvYmFtb3MgZWwgdGlwbyBsYXMgZWRhZGVzIGRlIGxhcyB2aWN0aW1hcy4KCmBgYHtyfQpjbGFzcyh2aWN0aW1hcyRFZGFkKQpgYGAKCgpIYXkgcXVlIHRyYW5zZm9ybWFybG8gZW4gbnVtZXJpY28uCgpgYGB7cn0KdmljdGltYXMkRWRhZDwtYXMuaW50ZWdlcih2aWN0aW1hcyRFZGFkKQpgYGAKCgpWZW1vcyBsYXMgZWRhZGVzIGRlIGxhcyBwZXJzb25hcyBpbnZvbHVjcmFkYXMuCgpgYGB7cn0KdW5pcXVlKHZpY3RpbWFzJEVkYWQpCmBgYAoKClRvbWFtb3MgY29tbyBlcnJvciBsYXMgZWRhZGVzIG1heW9yZXMgYSAxMTIgYcOxb3MgKHF1ZSBlcyBsYSBwZXJzb25hIG3DoXMgdmllamEgZGUgRXNwYcOxYSkgeSBsYXMgYWdydXBhbW9zIGVuIGxvcyBkZXNjb25vY2lkb3MuCgpgYGB7cn0KdmljdGltYXMkRWRhZD0gaWZlbHNlKHZpY3RpbWFzJEVkYWQgPiAxMTIsIE5BLCB2aWN0aW1hcyRFZGFkKQpgYGAKCgpDb21wcm9iYW1vcy4KCmBgYHtyfQp1bmlxdWUodmljdGltYXMkRWRhZCkKYGBgCgoKUmV2aXNhbW9zIGVsIHRpcG8gZGUgcGVyc29uYSBxdWUgc2UgcmVmaWVyZSBhbCBwYXBlbCBkZSBsYSB2aWN0aW1hLCBlcyBkZWNpciwgc2kgZXJhIGVsIGNvbmR1Y3RvciwgZWwgcGFzYWplcm8sIHBlYXRvbiwgZXRjLgoKYGBge3J9CnVuaXF1ZSh2aWN0aW1hcyRUaXBvUGVyc29uYSkKYGBgCgoKRWwgdHJpYWplIHNlIHJlZmllcmUgYSBsYSBncmF2ZWRhZCBkZWwgaGVyaWRvLgoKYGBge3J9CnVuaXF1ZSh2aWN0aW1hcyRUcmlhamVWaWN0aW1hKQpgYGAKCgpQYXJhIGVsIGFuYWxpc2lzIGFncnVwYW1vcyBlbiBsZXZlLCBncmF2ZSB5IG11ZXJ0by4KCmBgYHtyfQp2aWN0aW1hcyRUcmlhamVWaWN0aW1hPC1pZmVsc2UodmljdGltYXMkVHJpYWplVmljdGltYSA9PSAiRmVyaXQgbGxldTogSG9zcGl0YWxpdHphY2nDsyBmaW5zIGEgMjRoIiwgIkZlcml0IGxsZXUiLCB2aWN0aW1hcyRUcmlhamVWaWN0aW1hKQp2aWN0aW1hcyRUcmlhamVWaWN0aW1hPC1pZmVsc2UodmljdGltYXMkVHJpYWplVmljdGltYSA9PSAiRmVyaXQgbGxldTogQW1iIGFzc2lzdMOobmNpYSBzYW5pdMOgcmlhIGVuIGxsb2MgZCdhY2NpZGVudCIsICJGZXJpdCBsbGV1IiwgdmljdGltYXMkVHJpYWplVmljdGltYSkKdmljdGltYXMkVHJpYWplVmljdGltYTwtaWZlbHNlKHZpY3RpbWFzJFRyaWFqZVZpY3RpbWEgPT0gIkZlcml0IGxsZXU6IFJlYnV0amEgYXNzaXN0w6huY2lhIHNhbml0w6ByaWEiLCAiRmVyaXQgbGxldSIsIHZpY3RpbWFzJFRyaWFqZVZpY3RpbWEpCnZpY3RpbWFzJFRyaWFqZVZpY3RpbWE8LWlmZWxzZSh2aWN0aW1hcyRUcmlhamVWaWN0aW1hID09ICJGZXJpdCBncmV1OiBob3NwaXRhbGl0emFjacOzIHN1cGVyaW9yIGEgMjRoIiwgIkZlcml0IGdyZXUiLCB2aWN0aW1hcyRUcmlhamVWaWN0aW1hKQp2aWN0aW1hcyRUcmlhamVWaWN0aW1hPC1pZmVsc2UodmljdGltYXMkVHJpYWplVmljdGltYSA9PSAiTW9ydCAoZGlucyAyNGggcG9zdGVyaW9ycyBhY2NpZGVudCkiLCAiTW9ydCIsIHZpY3RpbWFzJFRyaWFqZVZpY3RpbWEpCmBgYAoKCkNvbXByb2JhbW9zLgoKYGBge3J9CnVuaXF1ZSh2aWN0aW1hcyRUcmlhamVWaWN0aW1hKQpgYGAKCllhIHRlbmVtb3MgbG9zIGRhdG9zIGxpbXBpb3MgcG9yIGxvIHF1ZSBwcm9jZWRlbW9zIGEgaW50ZXJwcmV0YXJsb3MuICAKCgojIyBHcmFmaWNvcwoKClByaW1lcm8gaW5zdGFsYW1vcyBnZ3Bsb3QyIHkgbGxhbWFtb3MgYSBsYSBsaWJyZXJpYS4KCmBgYHtyfQppbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikKbGlicmFyeShnZ3Bsb3QyKQpgYGAKCgpBaG9yYSBncmFmaWNhbW9zIHVuIGhpc3RvZ3JhbWEgY29uIGxhIGNhbnRpZGFkIGRlIHZpY3RpbWFzIHNlZ8O6biBsYSBlZGFkIHV0aWxpemFuZG8gZW4gZWwgZWplIHggbGEgZXNjYWxhIGRlIDUgYcOxb3MuCgpgYGB7cn0KZ2dwbG90KGRhdGE9dmljdGltYXMsIGFlcyh2aWN0aW1hcyRFZGFkKSkgKyAKICBnZW9tX2hpc3RvZ3JhbShicmVha3M9c2VxKDAsIDEwMCwgYnkgPSA1KSwgCiAgICAgICAgICAgICAgICAgY29sPSJyZWQiLCAKICAgICAgICAgICAgICAgICBhZXMoZmlsbD0uLmNvdW50Li4pKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudCgiTsO6bWVybyB2aWN0aW1hcyIsIGxvdyA9ICJncmVlbiIsIGhpZ2ggPSAicmVkIikgKwpsYWJzKHRpdGxlPSJIaXN0b2dyYW1hIG7Dum1lcm8gZGUgdmljdGltYXMgcG9yIGVkYWQiKSArCmxhYnMoeD0iRWRhZCIsIHk9IkNhbnRpZGFkIikKYGBgCgpFbiBlc3RlIGhpc3RvZ3JhbWEgcG9kZW1vcyB2ZXIgdW5hIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBkZSBsYSBjYW50aWRhZCBkZSB2aWN0aW1hcyBzZWfDum4gbGEgZWRhZC4gRWwgaGlzdG9ncmFtYSBpbmNsdXllIGEgc3UgdmV6IHVuIG1hcGEgZGUgY2Fsb3IgcXVlIHBlcm1pdGUgdW5hIHZpc3VhbGl6YWNpw7NuIG3DoXMgcsOhcGlkYS4gU2UgcHVlZGUgb2JzZXJ2YXIgcXVlIGxhIG1heW9yaWEgZGUgbGFzIHZpY3RpbWFzIHNlIGNvbmNlbnRyYW4gZW4gbGEgZWRhZCBkZSAyMCBhIDMwIGHDsW9zLgoKQWhvcmEgdmVyZW1vcyBsYXMgZXN0YWTDrXN0aWNhcyBwcmluY2lwYWxlcyBkZSBsYSBlZGFkOgoKYGBge3J9CnN1bW1hcnkodmljdGltYXMkRWRhZCkKYGBgCkxhIGVkYWQgbcOtbmltYSBkZSBsYXMgdmljdGltYXMgZXMgZGUgMCwgbG8gcXVlIHB1ZWRlIGltcGxpY2FyIHF1ZSBoYXkgbmnDsW9zIG1lbm9yZXMgYSAxIGHDsW8gaW52b2x1Y3JhZG9zIHkgbGEgZWRhZCBwcm9tZWRpbyBlcyBkZSAzOCBhw7Fvcy4KCkEgY29udGludWFjacOzbiByZWFsaXphbW9zIHVuIGhpc3RvZ3JhbWEgZGUgbGEgY2FudGlkYWQgZGUgYWNjaWRlbnRlcyBzZWfDum4gbGEgYW50aWd1ZWRhZCBkZWwgY2FybmV0LiBQYXJhIGVsbG8gc2UgdXRpbGl6YSBlbiBlbCBlamUgeCBsYSBlc2NhbGEgZGUgNSBhw7FvcwoKYGBge3J9CmdncGxvdChkYXRhPXZlaGljdWxvcywgYWVzKHZlaGljdWxvcyRBbnRpZ19jYXJuZXQpKSArIAogIGdlb21faGlzdG9ncmFtKGJyZWFrcz1zZXEoMCwgNzAsIGJ5ID0gNSksIAogICAgICAgICAgICAgICAgIGNvbD0iYmx1ZSIsIAogICAgICAgICAgICAgICAgIGFlcyhmaWxsPS4uY291bnQuLikpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KCJOw7ptZXJvIHZpY3RpbWFzIiwgbG93ID0gImdyZWVuIiwgaGlnaCA9ICJkYXJrYmx1ZSIpICsKbGFicyh0aXRsZT0iSGlzdG9ncmFtYSBuw7ptZXJvIGRlIHZpY3RpbWFzIHBvciBhbnRpZ3VlZGFkIGRlIGNhcm5ldCIpICsKbGFicyh4PSJBbnRpZ3VlZGFkIiwgeT0iQ2FudGlkYWQiKQpgYGAKCkVuIGVzdGUgaGlzdG9ncmFtYSBwb2RlbW9zIG9ic2VydmFyIGNvbW8gZGlzbWludXllIGVsIG7Dum1lcm8gZGUgYWNjaWRlbnRlcyBhbCBjcmVjZXIgZGUgbGEgYW50aWd1ZWRhZCBkZWwgY2FybmV0IGRlIGNvbmR1Y2lyLgoKVmVtb3MgbGFzIGVzdGFkaXN0aWNhcyBwcmluY2lwYWxlcyBkZSBsYSBhbnRpZ3VlZGFkIGRlIGNhcm5ldC4KCmBgYHtyfQpzdW1tYXJ5KHZlaGljdWxvcyRBbnRpZ19jYXJuZXQpCmBgYAoKCkFob3JhIGluc3RhbGFtb3MgZWwgcGFxdWV0ZSBkZSBUaWR5dmVyc2UgcGFyYSBwb2RlciB1dGlsaXphciBsYSBsaWJyZXJpYSBkZSBkcGx5ciBxdWUgbm9zIHBlcm1pdGUgYW5hbGl6YXIgeSBtYW5pcHVsYXIgZGF0b3MgZW4gdW4gRGF0YUZyYW1lCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKbGlicmFyeShkcGx5cikKYGBgCgoKQWdydXBhbW9zIHBvciBkw61hIGRlIHNlbWFuYSB5IGdyYWZpY2Ftb3MgcGFyYSB2ZXIgbGEgdGVuZGVuY2lhLgoKYGBge3J9ClBvckRpYTwtIHZpY3RpbWFzICU+JQogICAgZ3JvdXBfYnkoRGlhU2VtYW5hKSAlPiUKICAgIHN1bW1hcml6ZShUb3RhbD1uKCkpJT4lCiAgICBhcnJhbmdlKGRlc2MoVG90YWwpKQpQb3JEaWEKYGBgCgoKYGBge3J9CnBvc2l0aW9uczwtIGMoIkRpbGx1bnMiLCAiRGltYXJ0cyIsICJEaW1lY3JlcyIsICJEaWpvdXMiLCAiRGl2ZW5kcmVzIiwgIkRpc3NhYnRlIiwgIkRpdW1lbmdlIiApCgpnZ3Bsb3QoZGF0YS5mcmFtZSh2aWN0aW1hcyksIGFlcyh4PXZpY3RpbWFzJERpYVNlbWFuYSkpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz0gcG9zaXRpb25zLCBsYWJlbHM9YygiTHVuZXMiLCAiTWFydGVzIiwgIk1pZXJjb2xlcyIsICJKdWV2ZXMiLCAiVmllcm5lcyIsICJTYWJhZG8iLCAiRG9taW5nbyIpKSsKICBnZW9tX2JhcigpKwpsYWJzKHRpdGxlPSJIaXN0b2dyYW1hIG7Dum1lcm8gZGUgdmljdGltYXMgcG9yIGTDrWEgZGUgbGEgc2VtYW5hIikgKwpsYWJzKHg9IkRpYXMgZGUgc2VtYW5hIiwgeT0iQ2FudGlkYWQiKQoKYGBgCgpDb24gZWwgZ3LDoWZpY28gYW50ZXJpb3IgcG9kZW1vcyBvYnNlcnZhciBxdWUgbG9zIGFjY2lkZW50ZXMgdGllbmVuIHVuYSB0ZW5kZW5jaWEgY3JlY2llbnRlIGxvcyBkw61hcyBkZSBzZW1hbmEsIHRlbmllbmRvIHVuIHBpY28gbG9zIGTDrWFzIHZpZXJuZXMgeSBxdWUgZXN0b3MgZGlzbWludXllbiBjb25zaWRlcmFibGVtZW50ZSBsb3MgZmluZXMgZGUgc2VtYW5hLCBlbiBlc3BlY2lhbCBlbCBkb21pbmdvLiAKCgpBaG9yYSB2YW1vcyBhIGdyYWZpY2FyIGxvcyBob3Jhcmlvcy4gCgpgYGB7cn0KcG9zPC0gYygiTWF0w60iLCAiVGFyZGEiLCAiTml0IikKCmdncGxvdChkYXRhLmZyYW1lKHZpY3RpbWFzKSwgYWVzKHg9dmljdGltYXMkSG9yYXJpbykpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz0gcG9zLCBsYWJlbHM9YygiTWHDsWFuYSIsICJUYXJkZSIsICJOb2NoZSIpKSsKICBnZW9tX2JhcigpKwpsYWJzKHRpdGxlPSJIaXN0b2dyYW1hIG7Dum1lcm8gZGUgdmljdGltYXMgcG9yIGhvcmFyaW8iKSArCmxhYnMoeD0iSG9yYXJpbyIsIHk9IkNhbnRpZGFkIikKYGBgCgpQb2RlbW9zIG9ic2VydmFyIHF1ZSBsYSBtYXlvcsOtYSBkZSBsb3MgYWNjaWRlbnRlcyBvY3VycmVuIHBvciBsYSB0YXJkZS4gCgoKQWdydXBhbW9zIGxvcyB0aXBvcyBkZSBjYXJuZXQgeSBwb3IgdmVoaWN1bG9zLgoKYGBge3J9ClRpcG9DYXJuZXQ8LSB2ZWhpY3Vsb3MgJT4lCiAgICBncm91cF9ieShDYXJuZXQpICU+JQogICAgc3VtbWFyaXplKFRvdGFsPW4oKSklPiUKICAgIGFycmFuZ2UoZGVzYyhUb3RhbCkpClRpcG9DYXJuZXQKYGBgCgoKYGBge3J9ClRpcG9WZWhpY3VsbzwtIHZlaGljdWxvcyAlPiUKICAgIGdyb3VwX2J5KE1vZGVsbykgJT4lCiAgICBzdW1tYXJpemUoVG90YWw9bigpKSU+JQogICAgYXJyYW5nZShkZXNjKFRvdGFsKSkKVGlwb1ZlaGljdWxvCmBgYAoKCkdyYWZpY2Ftb3MgcGFyYSB2ZXIgbGEgY2FudGlkYWQgZGUgYWNjaWRlbnRlcyBwb3IgYmFycmlvLgoKYGBge3J9CmdncGxvdChkYXRhLmZyYW1lKHZpY3RpbWFzKSwgYWVzKHg9dmljdGltYXMkRGlzdHJpdG8pKSArCiAgZ2VvbV9iYXIoY29sPSAiYmx1ZSIgLGZpbGw9ImJsdWUiKSsKbGFicyh0aXRsZT0iSGlzdG9ncmFtYSBuw7ptZXJvIGRlIHZpY3RpbWFzIHBvciBkaXN0cml0byIpICsKbGFicyh4PSJEaXN0cml0byIsIHk9IkNhbnRpZGFkIikKYGBgCkVsIGRpc3RyaXRvIGNvbiBtYXlvciBjYW50aWRhZCBkZSBhY2NpZGVudGVzIGVzIGVsIEVpeGFtcGxlIG8gZW4gY2FzdGVsbGFubywgZWwgRW5zYW5jaGUsIHF1ZSBlcyBlbCB0aWVuZSBtYXlvciBjYW50aWRhZCBkZSBhY2NpZGVudGVzLiBDYWJlIGRlc3RhY2FyIHF1ZSBlcyBlbCBkaXN0cml0byBtw6FzIHBvYmxhZG8gZGUgQmFyY2Vsb25hIGVuIHRlcm1pbm9zIHJlbGF0aXZvcyB5IGFic29sdXRvcy4KCkNyZWFtb3MgdW5hIHRhYmxhIHBhcmEgdmVyIGxhIGNhbnRpZGFkIGRlIGFjY2lkZW50ZXMgc2Vnw7puIGVsIGTDrWEgZGUgc2VtYW5hIHkgZWwgaG9yYXJpbyB5IGxvIGdyYWZpY2Ftb3MgZW4gdW4gbWFwYSBkZSBjYWxvci4KCmBgYHtyfQpudWV2YTwtdmljdGltYXMgJT4lCiAgZ3JvdXBfYnkoRGlhU2VtYW5hLCBIb3JhcmlvKSAlPiUKICBzdW1tYXJpemUoVG90YWw9bigpKQpgYGAKCmBgYHtyfQoKcG9zaXRpb25zPC0gYygiRGlsbHVucyIsICJEaW1hcnRzIiwgIkRpbWVjcmVzIiwgIkRpam91cyIsICJEaXZlbmRyZXMiLCAiRGlzc2FidGUiLCAiRGl1bWVuZ2UiKQoKbnVldmEkSG9yYXJpbyA8LSBmYWN0b3IobnVldmEkSG9yYXJpbywgbGV2ZWxzID0gYygiTWF0w60iLCAiVGFyZGEiLCAiTml0IiksIGxhYmVscz1jKCJNYcOxYW5hIiwgIlRhcmRlIiwgIk5vY2hlIikpCgpnZ3Bsb3QobnVldmEsIGFlcyh4ID0gbnVldmEkRGlhU2VtYW5hLCB5ID0gbnVldmEkSG9yYXJpbywgZmlsbCA9IG51ZXZhJFRvdGFsKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz0gcG9zaXRpb25zLCBsYWJlbHM9YygiTHVuZXMiLCAiTWFydGVzIiwgIk1pZXJjb2xlcyIsICJKdWV2ZXMiLCAiVmllcm5lcyIsICJTYWJhZG8iLCAiRG9taW5nbyIpKSArIGdlb21fdGlsZSgpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJ3aGl0ZSIsIGhpZ2ggPSAic3RlZWxibHVlIikrCiAgbGFicyh4ID0gIkTDrWEgU2VtYW5hIiwgeSA9ICJIb3JhcmlvIiwgZmlsbCA9ICJOw7ptZXJvIEFjY2lkZW50ZXMiLCB0aXRsZSA9ICJNYXBhIGRlIGNhbG9yIG7Dum1lcm8gZGUgdmljdGltYXMgcG9yIGTDrWEgZGUgbGEgc2VtYW5hIHkgaG9yYXJpbyIpCmBgYApFc3RlIGdyw6FmaWNvIG5vcyBwZXJtaXRlIG9ic2VydmFyIHF1ZSBsb3MgZMOtYXMgY29uIG3DoXMgYWNjaWRlbnRlcyBzb24gbG9zIHZpZXJuZXMgcG9yIGxhIHRhcmRlLiAKCiMjIE1hcGFzCgoKKk5vdGE6IHBhcmEgZGlzZcOxYXIgdW4gcHVudG8gZW4gdW4gbWFwYSBjb24gbGEgbGlicmVyaWEgY2FydG9jaXVkYWQsIGhhY2UgZmFsdGEgY29ub2NlciBzdSBsYXRpdHVkIHkgbG9uZ2l0dWQuIFBvciBlc3RlIHRyYWJham8sIGRlY2lkaW1vcyB1dGlsaXphciBzw7NsbyBsYXMgYmFzZXMgZGUgZGF0b3MgZGUgMjAxNiB5IDIwMTcsIHF1ZSB5YSBjb250aWVuZW4gbG9zIGRhdG9zIGRlIGxhdGl0dWQgeSBsb25naXR1ZCBhIHBhcnRlIGRlIGxhcyBjb29yZGVuYWRhcyBVVE0sIGVudG9uY2VzIGVzdGUgcHJvY2VkaW1pZW50byByZXN1bHRhIHJlZG9uZGFudGUuIERlY2lkaW1vcyBzZWd1aXIgZXN0ZSBjYW1pbm8gcG9ycXVlIGxhcyBiYXNlcyBkZSBkYXRvcyBkZSBsb3MgYcOxb3MgYW50ZXJpb3JlcyBzw7NsbyBjb250aWVuZW4gbGFzIGNvb3JkZW5hZGFzIFVUTSB5IGVudG9uY2VzIG5vcyBwYXJlY2nDsyBpbnRlcmVzYW50ZSBlbmNvbnRyYXIgdW5hIHNvbHVjacOzbiBhIGVzdGUgcHJvYmxlbWEuKgoKCkNyZWFtb3MgdW4gbnVldm8gRGF0YUZyYW1lIGVsaW1pbmFuZG8gZGVsIERhdGFGcmFtZSBvcmlnaW5hbCBsYXMgZmlsYXMgY29uIGNvb3JkZW5hZGFzIG51bGFzIG8gPDAuCgpgYGB7cn0KdmljdGltYXNfc2luX2Nvb3JkX251bGFzIDwtIHZpY3RpbWFzWyghaXMubmEodmljdGltYXMkQ19VVE1fWCkgJiAhaXMubmEodmljdGltYXMkQ19VVE1fWSkgJiB2aWN0aW1hcyRDX1VUTV9YPjAgJiB2aWN0aW1hcyRDX1VUTV9ZPjApLCBdCnZpY3RpbWFzX3Npbl9jb29yZF9udWxhc1soaXMubmEodmljdGltYXNfc2luX2Nvb3JkX251bGFzJENfVVRNX1gpIHwgaXMubmEodmljdGltYXNfc2luX2Nvb3JkX251bGFzJENfVVRNX1kpIHwgdmljdGltYXNfc2luX2Nvb3JkX251bGFzJENfVVRNX1g8MCB8IHZpY3RpbWFzX3Npbl9jb29yZF9udWxhcyRDX1VUTV9ZPDApLCBdCmhlYWQodmljdGltYXNfc2luX2Nvb3JkX251bGFzKQpgYGAKCgpJbnN0YWxhbW9zIGxvcyBwYXF1ZXRlcyBuZWNlc2FyaW9zIHkgdHJhc2Zvcm1hbW9zIGxhcyBjb29yZGVuYWRhcyBVVE0gZW4gbGF0aXR1ZCB5IGxvbmdpdHVkLgoKYGBge3J9CgppbnN0YWxsLnBhY2thZ2VzKCJzcCIpCmxpYnJhcnkoc3ApICAjIHZlY3RvciBkYXRhCmluc3RhbGwucGFja2FnZXMoInJhc3RlciIpCmxpYnJhcnkocmFzdGVyKSAgIyByYXN0ZXIgZGF0YQppbnN0YWxsLnBhY2thZ2VzKCJyZ2RhbCIpCmxpYnJhcnkocmdkYWwpICAjIGlucHV0L291dHB1dCwgcHJvamVjdGlvbnMKaW5zdGFsbC5wYWNrYWdlcygicmdlb3MiKQpsaWJyYXJ5KHJnZW9zKSAgIyBnZW9tZXRyeSBvcHMKCnV0bWNvb3I8LVNwYXRpYWxQb2ludHModmljdGltYXNfc2luX2Nvb3JkX251bGFzWywgYygiQ19VVE1fWCIsICJDX1VUTV9ZIildLCBwcm9qNHN0cmluZz1DUlMoIitwcm9qPXV0bSArem9uZT0zMSIpKQpsb25nbGF0Y29vcjwtc3BUcmFuc2Zvcm0odXRtY29vcixDUlMoIitwcm9qPWxvbmdsYXQiKSkKaGVhZChsb25nbGF0Y29vcikKYGBgCgoKQcOxYWRpbW9zIGxvcyBjYW1wb3MgZGUgbGF0aXR1ZCB5IGxvbmdpdHVkIGFsIERhdGFGcmFtZS4gTm9zIGRhbW9zIGN1ZW50YSBxdWUgaGF5IHVuIGVycm9yIGVuIGxvcyB2YWxvcmVzIGRlIGxhcyBjb29yZGVuYWRhcyBVVE0gcXVlIGdlbmVyYSB1biBkZXNsaXphbWllbnRvIGRlIGxvcyBwdW50b3MgZW4gZWwgbWFwYS4gQWZvcnR1bmFkYW1lbnRlLCBwYXJhIGFycmVnbGFyIGVzdGUgZXJyb3IgZXMgc3VmaWNpZW50ZSByZXN0YXIgYSBsYXRpdHVkIHkgbG9uZ2l0dWQgdW5vcyB2YWxvcmVzIGZpam9zLgoKYGBge3J9CnZpY3RpbWFzX3Npbl9jb29yZF9udWxhcyRMb25nIDwtIGxvbmdsYXRjb29yJENfVVRNX1gtMC4wMDExMDMxNDUKdmljdGltYXNfc2luX2Nvb3JkX251bGFzJExhdCA8LSBsb25nbGF0Y29vciRDX1VUTV9ZLTAuMDAxODQ2NDkKaGVhZCh2aWN0aW1hc19zaW5fY29vcmRfbnVsYXMpCmBgYAoKCkRpc2XDsWFtb3MgZW4gZWwgbWFwYSB0b2RvcyBsb3MgcHVudG9zIGRvbmRlIHNlIGhheWEgdGVuaWRvIHZpY3RpbWFzIGRlIGFjY2lkZW50ZXMgZHVyYW50ZSBsb3MgYcOxb3MgMjAxNiB5IDIwMTcuCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygiZGV2dG9vbHMiKQpsaWJyYXJ5KGRldnRvb2xzKQppbnN0YWxsX2dpdGh1Yigick9wZW5TcGFpbi9jYVJ0b2NpdWRhZCIpCmxpYnJhcnkoY2FSdG9jaXVkYWQpCmluc3RhbGwucGFja2FnZXMoImdnbWFwIikKbGlicmFyeShnZ21hcCkKCmJjbiA8LSBjYXJ0b2NpdWRhZF9nZW9jb2RlKCJiYXJjZWxvbmEiKQptYXBhX2JjbiA8LSBjYXJ0b2NpdWRhZF9nZXRfbWFwKGMoYmNuJGxhdCwgYmNuJGxuZyksIDIpCm1hcGEgPC0gZ2dtYXA6OmdnbWFwKG1hcGFfYmNuKQptYXBhICsgZ2VvbV9wb2ludChhZXMoeCA9IExvbmcsIHkgPSBMYXQpLCBkYXRhID0gdmljdGltYXNfc2luX2Nvb3JkX251bGFzLCBzaXplID0gMSkKYGBgCgo=